24点——判断4个数能否经过运算使得结果为24
rqnoj74
Attention:
1.容易忽略(a[1]_a[2])_(a[3]_a[4]) 模式
2.通过两个整数相除,若保存结果为实型形式,不仅设置保存结果的变量为实型,而且还要1.0*x/y。
Way1:
从所有的数中任意找到两个,并选择任意运算符并运算,使得两个数变成一个数,最后只剩下一个数,则该数为式子的值。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 5 //正常思路的做法 6 7 struct node 8 { 9 double a[5]; 10 }ori; 11 long sym[5]; 12 13 void work(struct node s,long num) 14 { 15 if (num==1) 16 { 17 if (fabs(s.a[1]-24.0)<0.0000000001) 18 { 19 printf("yes\n"); 20 exit(0); 21 } 22 return ; 23 } 24 long i,j; 25 struct node ss; 26 for (i=1;i<=num;i++) 27 for (j=1;j<=num;j++) 28 if (i!=j) 29 { 30 ss=s; 31 switch(sym[num]) 32 { 33 case 1: 34 ss.a[i]=ss.a[i]+ss.a[j]; 35 break; 36 case 2: 37 ss.a[i]=ss.a[i]-ss.a[j]; 38 break; 39 case 3: 40 ss.a[i]=ss.a[i]*ss.a[j]; 41 break; 42 case 4: 43 if (ss.a[j]==0) 44 return ; 45 else 46 ss.a[i]=1.0*ss.a[i]/ss.a[j]; 47 } 48 //set in 1~num 49 if (i==num) 50 ss.a[j]=ss.a[i]; 51 else 52 ss.a[j]=ss.a[num]; 53 work(ss,num-1); 54 } 55 } 56 57 int main() 58 { 59 char c[3]; 60 long i,s; 61 for (i=1;i<=4;i++) 62 { 63 scanf("%s",c); 64 if (c[1]=='0') 65 ori.a[i]=10; 66 else if (c[0]>='0' && c[0]<='9') 67 ori.a[i]=c[0]-48; 68 else if (c[0]=='A') 69 ori.a[i]=1; 70 else if (c[0]=='J') 71 ori.a[i]=11; 72 else if (c[0]=='Q') 73 ori.a[i]=12; 74 else 75 ori.a[i]=13; 76 } 77 for (sym[4]=1;sym[4]<=4;sym[4]++) 78 for (sym[3]=1;sym[3]<=4;sym[3]++) 79 for (sym[2]=1;sym[2]<=4;sym[2]++) 80 work(ori,4); 81 printf("no\n"); 82 return 0; 83 }
Way2:
通过不同的运算方式得到24点
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 #define n 4 5 6 //如果输出不重复的所有的方法呢?应该怎么做? 7 8 //13*13*13*13=28561 9 //求出所有的方案 10 11 //4个数全排序,4!=24 12 //4个符号:+_-_*_/ 4!=24 13 //四个确定的数:共需要测试24*24=576次 14 15 long a[n+1]; 16 double s,t; 17 18 void match() 19 { 20 if (fabs(s-24)<0.0000000001) 21 { 22 long i; 23 printf("yes\n"); 24 exit(1); 25 } 26 } 27 28 void work1(long s1,long s2,long s3) 29 { 30 switch(s1) 31 { 32 case 1: 33 s=a[1]+a[2]; 34 break; 35 case 2: 36 s=a[1]-a[2]; 37 break; 38 case 3: 39 s=a[1]*a[2]; 40 break; 41 case 4: 42 if (a[2]==0) 43 return ; 44 else 45 s=1.0*a[1]/a[2]; 46 } 47 switch(s2) 48 { 49 case 1: 50 s=s+a[3]; 51 break; 52 case 2: 53 s=s-a[3]; 54 break; 55 case 3: 56 s=s*a[3]; 57 break; 58 case 4: 59 if (a[3]==0) 60 return ; 61 else 62 s=1.0*s/a[3]; 63 } 64 switch(s3) 65 { 66 case 1: 67 s=s+a[4]; 68 break; 69 case 2: 70 s=s-a[4]; 71 break; 72 case 3: 73 s=s*a[4]; 74 break; 75 case 4: 76 if (a[4]==0) 77 return ; 78 else 79 s=1.0*s/a[4]; 80 } 81 match(); 82 } 83 84 void work2(long s1,long s2,long s3) 85 { 86 switch(s1) 87 { 88 case 1: 89 s=a[1]+a[2]; 90 break; 91 case 2: 92 s=a[1]-a[2]; 93 break; 94 case 3: 95 s=a[1]*a[2]; 96 break; 97 case 4: 98 if (a[2]==0) 99 return ; 100 else 101 s=1.0*a[1]/a[2]; 102 } 103 switch(s2) 104 { 105 case 1: 106 t=a[3]+a[4]; 107 break; 108 case 2: 109 t=a[3]-a[4]; 110 break; 111 case 3: 112 t=a[3]*a[4]; 113 break; 114 case 4: 115 if (a[4]==0) 116 return ; 117 else 118 t=1.0*a[3]/a[4]; 119 } 120 switch(s3) 121 { 122 case 1: 123 s=s+t; 124 break; 125 case 2: 126 s=s-t; 127 break; 128 case 3: 129 s=s*t; 130 break; 131 case 4: 132 if (t==0) 133 return ; 134 else 135 s=1.0*s/t; 136 } 137 match(); 138 } 139 140 void sym() 141 { 142 long sym1,sym2,sym3; 143 //a_b_c_d 可一步算完 144 for (sym1=1;sym1<=4;sym1++) 145 for (sym2=1;sym2<=4;sym2++) 146 for (sym3=1;sym3<=4;sym3++) 147 work1(sym1,sym2,sym3); 148 149 //(a_b)_(c_d) 150 //两个符号优先级相同的符号可以更改顺序 151 // a/b*c=a*c/b a+b+c=a+c+b 然后再添任意一项,都可以一步算完,即用上面的方法 152 for (sym1=1;sym1<=2;sym1++) 153 for (sym3=1;sym3<=2;sym3++) 154 for (sym2=3;sym2<=4;sym2++) 155 work2(sym1,sym2,sym3); 156 for (sym1=3;sym1<=4;sym1++) 157 for (sym3=3;sym3<=4;sym3++) 158 for (sym2=1;sym2<=2;sym2++) 159 work2(sym1,sym2,sym3); 160 } 161 162 int main() 163 { 164 char c[3]; 165 long i,j,k,temp,x,y; 166 for (i=1;i<=n;i++) 167 { 168 scanf("%s",c); 169 if (c[1]=='0') 170 a[i]=10; 171 else if (c[0]>='0' && c[0]<='9') 172 a[i]=c[0]-48; 173 else if (c[0]=='A') 174 a[i]=1; 175 else if (c[0]=='J') 176 a[i]=11; 177 else if (c[0]=='Q') 178 a[i]=12; 179 else 180 a[i]=13; 181 } 182 for (i=1;i<4;i++) 183 for (j=i+1;j<=4;j++) 184 if (a[i]>a[j]) 185 { 186 temp=a[i]; 187 a[i]=a[j]; 188 a[j]=temp; 189 } 190 sym(); 191 for (i=1;i<24;i++) 192 { 193 //4 8 7 6 5 3 2 1 194 //5 8 7 6 4 3 2 1 195 //5 1 2 3 4 6 7 8 196 197 //从尾到头,找到第一个下降的a[j] 198 for (j=n-1;j>=1;j--) 199 if (a[j]<a[j+1]) 200 break; 201 //a[j]:从尾到a[j],找到第一个比a[j]大的数a[k] 202 for (k=n;k>j;k--) 203 if (a[k]>a[j]) 204 break; 205 temp=a[j]; 206 a[j]=a[k]; 207 a[k]=temp; 208 //数组:j+1~n reverse 209 x=j+1; 210 y=n; 211 while (x<y) 212 { 213 temp=a[x]; 214 a[x]=a[y]; 215 a[y]=temp; 216 x++; 217 y--; 218 } 219 sym(); 220 } 221 printf("no\n"); 222 return 0; 223 }
之后会讨论:
n个数的运算
求出所有满足结果为m的无重复的式子