一、问题描述
ZOJ 1003:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1003
标号为1~100的100个气球,两个人来踩气球,每个人初始分数为1,没踩破一个气球,则乘以该气球的数字。最后,两个人报出自己的分数。低分者要质疑高分者的分数,如果证实高分者的分数和低分者的分数矛盾,则低分者赢,否则高分者赢。
矛盾的意思就是两者分数不能仅使用1~100内的不同的数字作为因子乘出。
二、解题思路
使用回溯法。从100开始<这样,如果低分者本身就是1~100的数字,则首先将其当成低分者踩中相应的气球所得分>,尝试来先分解较小的数,直到分解完成或者分解失败。然后使用不同的因子开始分解较大的数,直到分解成功或者分解失败。
如果,两个数都分解成功或者小的数分解不成功,则不矛盾,高分者胜,否则,低分者胜。
三、程序实现
1 #include <iostream> 2 using namespace std; 3 4 int flag1,flag2 = 0; 5 6 //n表示大的数,m表示小的数 7 void DFS(int n , int m , int fac) 8 { 9 //********找到解的情况********** 10 if(flag1) return ; //两个用不同的因子分解成功,直接弹栈退出 11 12 if(n == 1 && m == 1) 13 { 14 flag1 = 1; 15 flag2 = 1; 16 return ; //找到不同因子分解成功,直接返回 17 } 18 19 //********大的只使用不同于小的的因子分解不成功****** 20 21 if(m == 1) 22 { 23 flag2 = 1; //小的数一旦分解成功,就立马将flag2置1 24 } 25 26 if(fac < 2) return ; //这次分解不成功 27 28 if(m%fac == 0) DFS(n,m/fac,fac-1); //先分解小的数 29 if(n%fac == 0) DFS(n/fac,m,fac-1); 30 31 DFS(n,m,fac-1); 32 } 33 34 int main() 35 { 36 int n,m = 0; 37 while(cin >> n >> m) 38 { 39 int tmp = 0; 40 if(m > n) 41 { 42 tmp = n; 43 n = m; 44 m = tmp; 45 } 46 flag1 = 0; 47 flag2 = 0; 48 49 DFS(n,m,100); 50 51 if(flag1 || !flag2) 52 cout << n <<endl; //两个用不同的因子分解成功或者小的数分解不成功 53 else 54 cout << m <<endl; //大的数无法用不同于小的数分解 55 56 n = 0; 57 m = 0; 58 } 59 return 0; 60 }
四、感想
自己通过自己独立分析问题,自己独立编程实现,最后这个题目顺利AC,这个节奏还是很好的~
最后,YZY,我想你!~
浙公网安备 33010602011771号