一、问题描述

             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 }
View Code

 

       四、感想

          自己通过自己独立分析问题,自己独立编程实现,最后这个题目顺利AC,这个节奏还是很好的~

          最后,YZY,我想你!~ 

posted on 2014-03-15 23:11  Oloo  阅读(573)  评论(0)    收藏  举报