zju 1003 Crashing Balloon
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个数,表示对应输入行获得胜利选手的得分.
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==0) return 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<=100) return 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<=100) return 1;
26 }
27 return 0;
28}
29
30int islie(unsigned long n){
31 if(isprim(n)&&n>100) return 1;
32 if(isfen(n)) return 0; else 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