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

The Primes
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就出来了,然后通过解六元六次方程便可以把剩下的数全部解出来了。

View Code
  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 }
 
原文地址:https://www.cnblogs.com/zhonghaoxi/p/2570516.html