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的无重复的式子

posted @ 2017-05-04 19:36  congmingyige  阅读(1076)  评论(0编辑  收藏  举报