题目描述

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.

  • Sample Input:
    343 49
    3599 610
    62 36
  • Sample Output:
    49
    610
    62
解题思路

总体思路,使用回溯法 。

首先,定义一个函数int test(int a, int b, int n)

  • 该函数返回1,
  • 当且仅当集合{2, 3, …, n}存在两个互不相交的子集合A = { x1, x2, … , xn}, B = {y1, y2, …, yn},
  • 使得 x1 * x2 * … * xn = a, y1 * y2 * … * yn = b。

该函数的代码如下

int test(int a, int b, int n)
{if(a==1 && b ==1) return 1;else if(n == 1) return 0;else {int t1, t2, t3;t1 = t2 = t3 =0;//分支1if(a%n == 0) {t1 = test(a/n, b, n-1);if(t1 == 1) return 1; //剪枝}//分支2if(b%n == 0) {t2 = test(a, b/n, n-1);if(t2 == 1) return 1; //剪枝}//分支3t3 = test(a, b, n-1);return t3;}
}

然后,在main函数中运用这个函数对每一对值a,b进行测试:

  • 假设a>b
  • 先测试a,b是否能同时满足,如果能,说明a,b都没撒谎,a赢;
  • 如果a,b不能同时满足,那么就有可能是因为a撒谎了,需要进行下面的测试;
  • 单独测试b,如果b可以单独满足,就可以认为是a撒谎了,b赢;
  • 如果b不可单独满足,则b撒谎了,根据规则,b输。

测试部分的代码:

while(scanf("%d %d", &a, &b) == 2 ){if(a < b) {int t = a; a = b; b = t;} //保证a>bint answer;if( test(a, b, 100) ) answer = a; //a,b都没撒谎,a赢else if( test(1, b, 100) ) answer = b; //b没撒谎且a撒谎了,b赢else answer = a; //b撒谎了,a赢printf("%d\n", answer);}
时间复杂度分析

递归的最大深度取决于int test(int a, int b, int n)函数的变量n
最坏情况下:
T(n)=3∗T(n−1)T(n) = 3*T(n-1) T(n)=3∗T(n−1)T(1)=1T(1) = 1 T(1)=1
所以,最坏情况下T(n)=log(3n)T(n)=log(3^n)T(n)=log(3n)。不过test函数中加入了剪枝策略,只要找到一个结果就可以立即返回,所以平均情况下不会这么慢。

POJ Accept 截图

完整代码
#include <stdio.h>
#include <stdlib.h>//测试a,b能否同时满足
int test(int a, int b, int n)
{if(a==1 && b ==1) return 1;else if(n == 1) return 0;else {int t1, t2, t3;t1 = t2 = t3 =0;//分支1if(a%n == 0) {t1 = test(a/n, b, n-1);if(t1 == 1) return 1; //剪枝}//分支2if(b%n == 0) {t2 = test(a, b/n, n-1);if(t2 == 1) return 1; //剪枝}//分支3t3 = test(a, b, n-1);return t3;}
}int main(void)
{int a, b;while(scanf("%d %d", &a, &b) == 2 ){if(a < b) {int t = a; a = b; b = t;} //保证a>bint answer;if( test(a, b, 100) ) answer = a; //a,b都没撒谎,a赢else if( test(1, b, 100) ) answer = b; //b没撒谎且a撒谎了,b赢else answer = a; //b撒谎了,a赢printf("%d\n", answer);}return 0;
}

ZOJ-1003-Crashing-Balloon相关推荐

  1. ZOJ1003 Crashing Balloon【水题】

    Crashing Balloon Time Limit: 2 Seconds Memory Limit: 65536 KB On every June 1st, the Children's Day, ...

  2. 【算法】算法之美—Crashing Balloon

    题目概述:Crashing Balloon On every  June 1st, the Children's Day, there will be a game named "crash ...

  3. 【Acm】算法之美—Crashing Balloon

    题目概述:Crashing Balloon On every  June 1st, the Children's Day, there will be a game named "crash ...

  4. ZJU1003 Crashing Balloon - 踩气球

    题目大意: 输入两个正整数x,y,判断x和y能否由1到100之间的整数乘积组成,数字不能重复使用. 分析: 想不到很好的方法,一般考虑用搜索来解决. 最初的时候没有考虑到数据范围.稍加分析,x,y最大 ...

  5. POJ ZOJ题目分类

    POJ,ZOJ题目分类(多篇整合版,分类很细致,全面) 标签: 题目分类POJ整理 2015-04-18 14:44 1672人阅读 评论(0) 收藏 举报 本文章已收录于: 分类: ACM资料(5) ...

  6. POJ,ZOJ题目分类(多篇整合版,分类很细致,全面)

    水题: 3299,2159,2739,1083,2262,1503,3006,2255,3094 初级: 一.基本算法:        (1)枚举 (1753,2965)       (2)贪心(13 ...

  7. ZOJ 题目分类,学校的一个巨巨做的。

     DP: 1011      NTA                    简单题 1013      Great Equipment        简单题 1024      Calendar ...

  8. linux脚本简介,Linux Shell脚本简介

    Shell 诞生于 Unix,是与 Unix/Linux 交互的工具,单独地学习 Shell 是没有意义的,请先参考Unix/Linux入门教程,了解 Unix/Lunix 基础. 近几年来,Shel ...

  9. c语言大小写字母互换1005,1005 Jugs,1005jugs

    1005 Jugs,1005jugs 辗转相减,新手入门题.两个容量的灌水题,无所谓最优解. 1 #include 2 3 intmain(){4 intA,B,T,sA,sB;5 while(sca ...

  10. poj题目详细分类及算法推荐题目

    DP:  1011   NTA                 简单题  1013   Great Equipment     简单题  1024   Calendar Game       简单题  ...

最新文章

  1. TensorFlow用法
  2. MySQL实验作业_MySQL作业
  3. 冷知识 —— 成语与典故
  4. Jquery tmpl模板中if条件有多个时的写法
  5. 04_ClickHouse表引擎概述、MergeTree系列引擎、Log系列引擎、集成引擎、特定功能的引擎(学习笔记)
  6. 昆明大专学计算机,昆明冶金高等专科学校2020年云南省高等教育招收中等职业学校学生 (计算机类)考试大纲...
  7. javafx中css选择器_JavaFX技巧12:在CSS中定义图标
  8. scrapy —— ImagePipeline
  9. springMVC学习-day02
  10. delphi制作上下开幕效果_显示产业国际盛会开幕,广州新型显示产值将突破2500亿...
  11. 自制三层架构代码生成器软件
  12. python的list的基本操作、list循环、切片、字典基本操作、字典嵌套、字符串常用方法...
  13. 虚拟服务器磁盘 厚置备置零,VMware ESXi 虚拟硬盘格式记录:厚置备延迟置零、厚置备置零、精简置备...
  14. c语言键盘输入今年的某月某日,题目:输入某年某月某日,判断这一天是这一年的第几天?...
  15. Android应用内设置多语言,可随系统语言改变而改变,也可设置app为固定语言不受系统语言影响
  16. 写给我的客户da辉狼
  17. shell之正则表达式
  18. python 数据、曲线平滑处理
  19. 蓝牙智能门锁现状分析
  20. 中国“苹果皮”之父:希望与苹果公司展开合作

热门文章

  1. 「易见股份」暴涨背后:炒区块链概念半年赚2亿
  2. 黑马头条项目-Vue-day10-小智同学聊天功能,退出功能的实现,websocket用法,白名单,关于nextTick()方法
  3. 导弹拦截(标题还有字数要求qwq)
  4. Gerrit报错:Permission denied (publickey)
  5. 数模技术转换应用于计算机控制,数模转换器的作用
  6. 信道容量 matlab,离散无记忆信道容量的matlab算法
  7. 射频通信PCC和SCC定义
  8. android 后台录制视频,Android实现视频录制
  9. Matlab图形中输入希腊字母
  10. 黄金矿工小游戏制作步骤