zju 1003 Crashing Balloon

做1003花了我半天的时间````` 才知道什么叫做痛苦了,写程序半个小时就搞定了,调试花了1下午。。。。
zju不给没有过的数据给我们看,完全像个无头苍蝇一样一遍一遍的检查程序,最后终于被Accpeted了,真激动啊。
我写的这个程序运行速度还是很快的,在forum上看到一个用C++写的并且通过了的程序(用STL写的,看不懂),测试15990个数据,发现我的程序的速度是那个的5倍^-^

开始翻译题目:zju-1003 踩气球
   每年6.1儿童节,儿童们会玩一个称为“踩爆气球的游戏”,规则很简单,在地上有100个标有1到100标签的气球。当裁判说“开始”后,2个初始分数都是1的选手,开始疯狂的踩爆气球,同时,把它们各自踩爆气球上的数字相乘。1分钟后,2个选手报出自己得到的分数。非正式的胜利者就是分数高的选手。
   为了避免争议,选手方面,有权怀疑胜利者的得分。如果可以判定2个选手中有1个说谎了,那么就认为分第的那个选手说的实话,因为如果他要说谎,一定会拿出一个更大的谎言。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. (sorry,这句实在不好翻译)
   例如,2个选手报的分数为343和49,那么很明显第一个选手在撒谎,因为唯一得到343分的途径是踩爆7和49气球,而唯一得到49的途径是踩爆49气球,所以一定有个人在说谎,因而第2个选手获得胜利。
   另一方面,如果2个选手报的分数为162和81,因为162可以等于2*3*27,81=1*81,所以不能判定2人是否有说谎,这是按照原始分判定。
   如果可以判定2个人都在说谎,比如10001 和10003,那么这是也按照原始分判定.
Input
  每行2个数,分别为2个选手报的分数.
Output
  每行1个数,表示对应输入行获得胜利选手的得分.

  1/* zju 1089
  2by woodfish
  3*/

  4
  5#include <stdio.h>
  6#include <math.h>
  7
  8int o[101],o2[101],flag,flag2;
  9int isprim(unsigned long n){
 10 int i;
 11 for(i=2;i<=sqrt(n);i++)
 12  if(n%i==0return 0;
 13 return 1;
 14}

 15
 16int isfen(unsigned long n) {
 17    int i;
 18    char c[101];
 19    for(i=1;i<100;i++) c[i]='1';
 20    if(n<=100return 1;
 21    for(i=100;i>=2;i--)
 22 if((n%i==0)&&(c[i]=='1')&&(n/i!=i)){
 23  n=n/i;
 24  c[i]='0';
 25  if(n<=100return 1;
 26 }

 27    return 0;
 28}

 29
 30int islie(unsigned long n){
 31 if(isprim(n)&&n>100return 1;
 32 if(isfen(n)) return 0else return 1;
 33}

 34
 35int ismatch2(unsigned long n2){
 36 int i;
 37 if(!flag2){
 38  if(isprim(n2)&&n2>100{flag2=0;return 0;}
 39  if(isprim(n2)&&n2<100{
 40   if(!o2[n2]) {flag2=0;return 0;}
 41   flag2=1;return flag2;
 42  }

 43  if(n2>100)
 44   for(i=100;i>1;i--)
 45   if((n2%i==0)&&o2[i]&&(n2/i!=i)) {
 46    o2[i]=0;
 47    ismatch2(n2/i);
 48    o2[i]=1;
 49   }

 50  if(n2<=100{
 51   if(o2[n2]) {flag2=1;return 1;}
 52   for(i=100;i>1;i--)
 53    if((n2%i==0)&&o2[i]&&(n2/i!=i)) {
 54     o2[i]=0;
 55     ismatch2(n2/i);
 56     o2[i]=1;
 57    }

 58   }

 59  }

 60}

 61
 62int ismatch(unsigned long n1,unsigned long n2){
 63 int i,k;
 64 if(!flag){
 65  if(isprim(n1)&&n1>100{flag=0;return 0;}
 66  if(isprim(n1)&&n1<100{
 67   if(!o[n1]) {flag=0;return 0;}
 68   o[n1]=0;
 69   for(k=1;k<101;k++) o2[k]=o[k];
 70   ismatch2(n2);
 71   o[n1]=1;
 72   flag=flag2;return flag;
 73  }

 74  if(n1>100)
 75   for(i=100;i>1;i--)
 76    if((n1%i==0)&&o[i]&&(n1/i!=i)){
 77     o[i]=0;
 78     ismatch(n1/i,n2);
 79     o[i]=1;
 80    }

 81  if(n1<=100{
 82   if(o[n1]) {
 83    o[n1]=0;
 84    for(k=1;k<101;k++) o2[k]=o[k];
 85    ismatch2(n2);
 86    if(flag2) {flag=1;return 1;}
 87    o[n1]=1;
 88   }

 89   if(!flag)
 90    for(i=100;i>1;i--)
 91     if((n1%i==0)&&o[i]&&(n1/i!=i)) {
 92      o[i]=0;
 93      ismatch(n1/i,n2);
 94      o[i]=1;
 95     }

 96  }

 97 }

 98}

 99
100int solve(unsigned long n1,unsigned long n2){
101 if(islie(n2)) {printf("%ld\n",n1);return 1;}
102 if(islie(n1)) {printf("%ld\n",n2);return 1;}
103 ismatch(n1,n2);
104 if(flag) {printf("%ld\n",n1);return 1;}
105 else{printf("%ld\n",n2);return 1;}
106}

107
108void main(){
109 unsigned long n1,n2;
110 int i;
111 while(scanf("%ld %ld",&n1,&n2)!=EOF){
112  if(n1<n2) {n1=n2+n1;n2=n1-n2;n1=n1-n2;}
113  for(i=1;i<=100;i++) o[i]=1;
114  flag=flag2=0;
115  solve(n1,n2);
116       }

117}

118
119

posted on 2006-11-10 18:46  woodfish  阅读(1976)  评论(1编辑  收藏  举报

导航