USACO 4.3.2 prime3
题目:
http://ace.delos.com/usacoprob2?a=0H14tt2CoyP&S=prime3
http://pingce.ayyz.cn:9000/usaco/data/20110129214306/index.html#Section_5.1
IOI'94
In the square below, each row, each column and the two diagonals can be read as a five digit prime number. The rows are read from left to right. The columns are read from top to bottom. Both diagonals are read from left to right.
+---+---+---+---+---+
| 1 | 1 | 3 | 5 | 1 |
+---+---+---+---+---+
| 3 | 3 | 2 | 0 | 3 |
+---+---+---+---+---+
| 3 | 0 | 3 | 2 | 3 |
+---+---+---+---+---+
| 1 | 4 | 0 | 3 | 3 |
+---+---+---+---+---+
| 3 | 3 | 3 | 1 | 1 |
+---+---+---+---+---+
- The prime numbers' digits must sum to the same number.
- The digit in the top left-hand corner of the square is pre-determined (1 in the example).
- A prime number may be used more than once in the same square.
- If there are several solutions, all must be presented (sorted in numerical order as if the 25 digits were all one long number).
- A five digit prime number cannot begin with a zero (e.g., 00003 is NOT a five digit prime number).
PROGRAM NAME: prime3
INPUT FORMAT
A single line with two space-separated integers: the sum of the digits and the digit in the upper left hand corner of the square.
SAMPLE INPUT (file prime3.in)
11 1
OUTPUT FORMAT
Five lines of five characters each for each solution found, where each line in turn consists of a five digit prime number. Print a blank line between solutions. If there are no prime squares for the input data, output a single line containing "NONE".
SAMPLE OUTPUT (file prime3.out)
The above example has 3 solutions.
11351 14033 30323 53201 13313 11351 33203 30323 14033 33311 13313 13043 32303 50231 13331
题解:
看着很和谐的搜索题又来了一道,但是这道题却也是最恶心的一道………………
首先把所有可能素数处理出来这是没说的,然后就开始搜索了………………网上MS有14重循环结束战斗的…………………………我觉得太可怕便换了种写法。
考虑以下将情况:
abcde
f g
h i
j k
lmnop
则有b,c,d,e,f,h,j,l!=0 l,m,n,o,p,e,g,i,k!=0,2,4,5,6,8,而它们共同形成了四个质数,于是我们便可以把除首位外没有偶数的质数,和每一位均不为0,2,4,5,6,8的质数处理出来,这样就可以把周围一层的四个质数全部处理出来,于是只剩下了中间的3*3de方阵。
abc
def
ghi
此时枚举a,b,然后c就出来了,然后通过解六元六次方程便可以把剩下的数全部解出来了。
1 /*
2 ID:zhongha1
3 PROB:prime3
4 LANG:C++
5 */
6
7 #include<cstdio>
8 #include<cstdlib>
9 #include<cstring>
10 #include<algorithm>
11
12 using namespace std;
13
14 int n,sum,l1,l2,l3,prime1[100000],prime2[100000],prime3[100000],map[6][6],ansl;
15
16 bool first=true,able[20][20];
17
18 struct node
19 {
20 node *next[10];
21 node()
22 {
23 for (int a=0;a<=9;a++)
24 next[a]=NULL;
25 }
26 }*root;
27
28 struct ans_node
29 {
30 int map[6][6];
31 void print()
32 {
33 if (!first) printf("\n");
34 first=false;
35 for (int a=1;a<=5;a++)
36 {
37 for (int b=1;b<=5;b++)
38 printf("%d",map[a][b]);
39 printf("\n");
40 }
41 }
42 bool operator<(const ans_node &c)const
43 {
44 for (int a=1;a<=5;a++)
45 for (int b=1;b<=5;b++)
46 if (map[a][b]!=c.map[a][b]) return map[a][b]<c.map[a][b];
47 return false;
48 }
49 }ans[10000];
50
51 bool prime(int now)
52 {
53 int orz=now,nowsum=0;
54 while (orz)
55 {
56 nowsum+=orz % 10;
57 orz/=10;
58 }
59 if (nowsum!=sum) return false;
60 for (int a=2;a*a<=now;a++)
61 if (now % a==0) return false;
62 able[now / 10000][now % 10]=true;
63 return true;
64 }
65
66 void check1(int now)
67 {
68 l1++;
69 prime1[l1]=now;
70 int orz=0;
71 while (now)
72 {
73 orz=orz*10+now % 10;
74 now/=10;
75 }
76 /*for (int a=1;a<=5;a++)
77 {
78 int hehe=orz % 10;
79 if (p->next[hehe]==NULL) p->next[hehe]=new node;
80 p=p->next[hehe];
81 orz/=10;
82 }*/
83 }
84
85 void check2(int now)
86 {
87 if (now / 10000!=n) return;
88 int l=0,r=l1;
89 while (l+1!=r)
90 {
91 int m=(l+r)>>1;
92 if (prime1[m]>=now) r=m;
93 else l=m;
94 }
95 if (prime1[r]!=now) return;
96 l2++;
97 prime2[l2]=now;
98 }
99
100 void check3(int now)
101 {
102 int orz=now;
103 while (orz)
104 {
105 int hehe=orz % 10;
106 if (hehe % 2==0 || hehe==5) return;
107 orz/=10;
108 }
109 l3++;
110 prime3[l3]=now;
111 }
112
113 bool check4(int a,int b,int c)
114 {
115 if (b % 10!=c / 10000) return false;
116 for (int d=1;d<=5;d++)
117 {
118 if (!able[a % 10][c % 10]) return false;
119 a/=10;
120 c/=10;
121 }
122 return true;
123 }
124
125 void fill(int a,int b,int c,int d)
126 {
127 for (int e=1;e<=5;e++)
128 {
129 map[1][6-e]=a % 10;
130 a/=10;
131 }
132 for (int e=1;e<=5;e++)
133 {
134 map[6-e][1]=b % 10;
135 b/=10;
136 }
137 for (int e=1;e<=5;e++)
138 {
139 map[5][6-e]=c % 10;
140 c/=10;
141 }
142 for (int e=1;e<=5;e++)
143 {
144 map[6-e][5]=d % 10;
145 d/=10;
146 }
147 }
148
149 bool exist(int now)
150 {
151 int l=0,r=l1;
152 while (l+1!=r)
153 {
154 int m=(l+r)>>1;
155 if (prime1[m]>=now) r=m;
156 else l=m;
157 }
158 if (prime1[r]!=now) return false;
159 else return true;
160 }
161
162 bool check_map()
163 {
164 for (int a=1;a<=5;a++)
165 for (int b=1;b<=5;b++)
166 if (map[a][b]<0 || map[a][b]>9) return false;
167 for (int a=1;a<=5;a++)
168 {
169 int now=0;
170 for (int b=1;b<=5;b++)
171 now=now*10+map[a][b];
172 if (!exist(now)) return false;
173 }
174 for (int a=1;a<=5;a++)
175 {
176 int now=0;
177 for (int b=1;b<=5;b++)
178 now=now*10+map[b][a];
179 if (!exist(now)) return false;
180 }
181 int now=0;
182 for (int a=1;a<=5;a++)
183 now=now*10+map[a][a];
184 if (!exist(now)) return false;
185 now=0;
186 for (int a=1;a<=5;a++)
187 now=now*10+map[6-a][a];
188 if (!exist(now)) return false;
189 return true;
190 }
191
192 void get_add_ans()
193 {
194 ansl++;
195 for (int a=1;a<=5;a++)
196 for (int b=1;b<=5;b++)
197 ans[ansl].map[a][b]=map[a][b];
198 }
199
200 int main()
201 {
202 freopen("prime3.in","r",stdin);
203 freopen("prime3.out","w",stdout);
204
205 scanf("%d%d",&sum,&n);
206 root=new node;
207 for (int a=10000;a<100000;a++)
208 if (prime(a))
209 {
210 check1(a);
211 check3(a);
212 }
213 for (int a=1;a<=l1;a++)
214 check2(prime1[a]);
215 for (int a=1;a<=l2;a++)
216 for (int b=1;b<=l2;b++)
217 if (able[prime2[b] % 10][prime2[a] % 10])
218 {
219 for (int c=1;c<=l3;c++)
220 if (able[n][prime3[c] % 10] && check4(prime2[a],prime2[b],prime3[c]))
221 {
222 for (int d=1;d<=l3;d++)
223 if (prime3[d] % 10==prime3[c] % 10 && check4(prime2[b],prime2[a],prime3[d]))
224 {
225 fill(prime2[a],prime2[b],prime3[c],prime3[d]);
226 for (map[2][2]=0;map[2][2]<=9;map[2][2]++)
227 for (map[3][2]=0;map[3][2]<=9;map[3][2]++)
228 {
229 map[4][2]=sum-map[1][2]-map[2][2]-map[3][2]-map[5][2];
230 int now=0;
231 for (int a=1;a<=5;a++)
232 now=now*10+map[a][2];
233 if (!exist(now)) continue;
234 now=(sum-map[2][1]-map[2][2]-map[2][5])+2*(sum-map[3][1]-map[3][2]-map[3][5])+(sum-map[4][1]-map[4][2]-map[4][5])+(sum-map[5][1]-map[4][2]-map[1][5])+(sum-map[1][1]-map[2][2]-map[5][5])-(sum-map[1][3]-map[5][3])-2*(sum-map[1][4]-map[5][4]);
235 if (now % 3!=0) continue;
236 map[3][3]=now / 3;
237 map[4][4]=sum-map[1][1]-map[2][2]-map[3][3]-map[5][5];
238 map[4][3]=sum-map[4][1]-map[4][2]-map[4][4]-map[4][5];
239 map[2][3]=sum-map[1][3]-map[3][3]-map[4][3]-map[5][3];
240 map[3][4]=sum-map[3][1]-map[3][2]-map[3][3]-map[3][5];
241 map[2][4]=sum-map[2][1]-map[2][2]-map[2][3]-map[2][5];
242 if (check_map()) get_add_ans();
243 }
244 }
245 }
246 }
247 sort(ans+1,ans+ansl+1);
248 for (int a=1;a<=ansl;a++)
249 ans[a].print();
250
251 return 0;
252 }