《ACM国际大学生程序设计竞赛题解Ⅰ》——模拟题
这篇文章来介绍一些模拟题,即一类按照题目要求将现实的操作转换成程序语言。
zoj1003:
On every June 1st, the Children's Day, there will be a game named "crashing balloon" on TV. The rule is very simple. On the ground there are 100 labeled balloons, with the numbers 1 to 100. After the referee shouts "Let's go!" the two players, who each starts with a score of "1", race to crash the balloons by their feet and, at the same time, multiply their scores by the numbers written on the balloons they crash. After a minute, the little audiences are allowed to take the remaining balloons away, and each contestant reports his\her score, the product of the numbers on the balloons he\she's crashed. The unofficial winner is the player who announced the highest score.
Inevitably, though, disputes arise, and so the official winner is not determined until the disputes are resolved. The player who claims the lower score is entitled to challenge his\her opponent's score. The player with the lower score is presumed to have told the truth, because if he\she were to lie about his\her score, he\she would surely come up with a bigger better lie. The challenge is upheld if the player with the higher score has a score that cannot be achieved with balloons not crashed by the challenging player. So, if the challenge is successful, the player claiming the lower score wins.
So, for example, if one player claims 343 points and the other claims 49, then clearly the first player is lying; the only way to score 343 is by crashing balloons labeled 7 and 49, and the only way to score 49 is by crashing a balloon labeled 49. Since each of two scores requires crashing the balloon labeled 49, the one claiming 343 points is presumed to be lying.
On the other hand, if one player claims 162 points and the other claims 81, it is possible for both to be telling the truth (e.g. one crashes balloons 2, 3 and 27, while the other crashes balloon 81), so the challenge would not be upheld.
By the way, if the challenger made a mistake on calculating his/her score, then the challenge would not be upheld. For example, if one player claims 10001 points and the other claims 10003, then clearly none of them are telling the truth. In this case, the challenge would not be upheld.
Unfortunately, anyone who is willing to referee a game of crashing balloon is likely to get over-excited in the hot atmosphere that he\she could not reasonably be expected to perform the intricate calculations that refereeing requires. Hence the need for you, sober programmer, to provide a software solution.
Input
Pairs of unequal, positive numbers, with each pair on a single line, that are claimed scores from a game of crashing balloon.
Output
Numbers, one to a line, that are the winning scores, assuming that the player with the lower score always challenges the outcome.
题目大意:给出两个整数n、m(假设m>n),请你判断是否存在一种方案,使得n = f1 * f2 *... , m=F1 * F2 *...,其中对于任意的i、j,有fi≠fj,fi≠Fj,fi∈[2,100]且fj∈[2,100]。
数理分析:其实对于题目大意的描述,笔者表述很抽象化,如果用文字描述,其实就是判断对于给出的两个整数n、m,进行因数分解(因子范围在1~100),能否得到两个完全不同的方案。假设我们已经得到了结果,我们先看看这个结果如何左右我们输出的结果。
如果存在这样一种方案,结合原文题意,这里驳回质疑,高分胜出,即输出m、n当中较高的那个。
如果不存在这样一种方案,则质疑成功,低分胜出,输出m、n中较小的那个。
这里注意到原文的一段话,“By the way, if the challenger made a mistake on calculating his/her score, then the challenge would not be upheld. For example, if one player claims 10001 points and the other claims 10003, then clearly none of them are telling the truth. In this case, the challenge would not be upheld.”这句话是说,如果m、n两者都没办法完成上述的因数分解,即用原文的话说是两个人都说谎,则不支持提出的质疑,按照原来的胜负态来处理,也就是高分或者获胜。
总结起来,如果想输出较小的数,当且仅当m、n在所以的因数分解中,n能够被因数分解但是m不能。而其余的情况都是输出较大数m。
搞清的如何输出,下面我们要解决的关键问题就是如何判断笔者在题目大意中描述的那个数学问题呢?
其实笔者感觉这道题放在模拟题中有点“干”,它其实涉及了数论的东西和dfs的思想(关于搜索后面会有一篇文章专门介绍)。
判断方法描述起来很简单,我们找到m、n所有的因数分解情况,然后按照给出的限制条件去判断即可。
但是如何巧妙的变成来实现这个过程呢?要先对m、n质因分解然后排列组合么?理论上可行但似乎有些繁琐。考虑到每个因子仅能出现一次的特点,我们利用dfs进行深搜,我们首先从枚举100开始枚举2~100这99个因子,一旦发现一个m或者n的因子pm或pn(假设当前找到了m的一个因子pm),那么我们可以将问题更加的微小化。即一开始,我们当前的问题是判断整数m、n是否能够得到两种不同的因数分解方案,因子范围是2~100,那么在找到了某个因子pm之后,我们的问题便可以缩小化成如下的等价形式,判断m/pm、n是否能够得到两种不同的因数分解方案,因子范围是2~pm-1,由此我们看到这递归的程序模式,其实如果熟悉欧几里得算法的读者,会更好的理解这个过程。
简单的参考代码如下。
#include<cstdio>
using namespace std;
bool atrue , btrue; int judge(int m,int n,int p)
{
if(atrue) return ;
if(n == && m == )
{
atrue = true;
btrue = true;
return ;
}
if(n == ) btrue = true; while(p > )
{
if(m%p == ) judge(m/p,n,p-);
if(n%p == ) judge(m,n/p,p-);
p--;
}
return ;
}
int main()
{
int a , b , temp;
while(scanf("%d%d",&a,&b) != EOF)
{
if(b > a)
{
temp = a;
a = b;
b = temp;
}
atrue = false;
btrue = false;
judge(a , b , ); if(!atrue && btrue)
printf("%d\n",b);
else
printf("%d\n",a);
}
}
《ACM国际大学生程序设计竞赛题解Ⅰ》——模拟题的更多相关文章
- 《ACM国际大学生程序设计竞赛题解Ⅰ》——基础编程题
这个专栏开始介绍一些<ACM国际大学生程序设计竞赛题解>上的竞赛题目,读者可以配合zju/poj/uva的在线测评系统提交代码(今天zoj貌似崩了). 其实看书名也能看出来这本书的思路,就 ...
- 《ACM国际大学生程序设计竞赛题解I》——6.10
Pku 1143: Description Christine and Matt are playing an exciting game they just invented: the Number ...
- 《ACM国际大学生程序设计竞赛题解I》——6.11
pku 1107: Description Weird Wally's Wireless Widgets, Inc. manufactures an eclectic assortment of sm ...
- 《ACM国际大学生程序设计竞赛题解I》——6.8
Poj1068: Description Let S = s1 s2...s2n be a well-formed string of parentheses. S can be encoded in ...
- 2018 ACM 国际大学生程序设计竞赛上海大都会部分题解
题目链接 2018 ACM 国际大学生程序设计竞赛上海大都会 下午午休起床被同学叫去打比赛233 然后已经过了2.5h了 先挑过得多的做了 .... A题 rand x*n 次点,每次judge一个点 ...
- 2018 ACM 国际大学生程序设计竞赛上海大都会赛
传送门:2018 ACM 国际大学生程序设计竞赛上海大都会赛 2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛2018-08-05 12:00:00 至 2018-08-05 17:00:0 ...
- 2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 F Color it
链接:https://www.nowcoder.com/acm/contest/163/F 来源:牛客网 2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 F Color it 时间限制:C ...
- 2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 F Color it (扫描线)
2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 F Color it (扫描线) 链接:https://ac.nowcoder.com/acm/contest/163/F来源:牛客网 时间 ...
- 2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 J Beautiful Numbers (数位DP)
2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 J Beautiful Numbers (数位DP) 链接:https://ac.nowcoder.com/acm/contest/163/ ...
随机推荐
- treeview右键添加新节点
private void advTree1_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Righ ...
- linux下启动oracle服务命令
以redflag(redhat /centos)linux下的 oracle 10g 为例: 如果oracle安装和配置都没有问题的话: 依次执行以下代码即可启动oracle服务. #su - ora ...
- Alljoyn 概述(2)
AllJoyn 基本概念 • 总线(Bus) – 实现P2P通信的基础 – AllJoyn 的底层协议类似于D-Bus,相当于是跨设备分布式的 D-Bus • 总线附件(Bus Attachment) ...
- POJ 1286 Necklaces of Beads (Burnside定理,有限制型)
题目链接:http://vjudge.net/problem/viewProblem.action?id=11117 就是利用每种等价情形算出置换节之后算组合数 #include <stdio. ...
- SGU 142.Keyword
时间限制:0.5s 空间限制:16M 题意 给出一个仅由'a',‘b’组成的字符串S,长度小于500 000,求一个由‘a’,‘b’组成的不是S子串的字符串T. 输出T的长度和T. Sample In ...
- PHP 用Class构造JSON数据
header('Content-type: appliction/json; charset=shift-JIS'); // error //{ // "result": fals ...
- Android 常用网站
Android Design : http://www.sunjw.us/adchs/index.html Android Developers : http://developer.android. ...
- 用硬件(Verilog)实现二进制码和格雷码的转换
格雷码(Gray code)是1880年由法国工程师Jean-Maurice-Emlle Baudot发明的一种编码,是一种绝对编码方式,典型格雷码是一种具有反射特性和循环特性的单步自补码,它的循环. ...
- Yosemite重置Dock的命令
备忘 defaults write com.apple.dock ResetLaunchPad -bool true killall Dock
- 转:几十种编程语言的快速入门教程- learnxinyminutes.com
原文来自于:http://top.jobbole.com/15551/ 这家网站的名称是 Learn X in Y minutes,包括了几十种编程语言的快速学习入门教程.打开几种编程语言来看了一下, ...