【HDOJ】1979 Fill the blanks

预处理+搜索剪枝。
4*4的边界上的数字必须是奇数。

  1 /* 1979 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <bitset>
 12 #include <algorithm>
 13 #include <cstdio>
 14 #include <cmath>
 15 #include <ctime>
 16 #include <cstring>
 17 #include <climits>
 18 #include <cctype>
 19 #include <cassert>
 20 #include <functional>
 21 #include <iterator>
 22 #include <iomanip>
 23 using namespace std;
 24 //#pragma comment(linker,"/STACK:102400000,1024000")
 25 
 26 #define sti                set<int>
 27 #define stpii            set<pair<int, int> >
 28 #define mpii            map<int,int>
 29 #define vi                vector<int>
 30 #define pii                pair<int,int>
 31 #define vpii            vector<pair<int,int> >
 32 #define rep(i, a, n)     for (int i=a;i<n;++i)
 33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 34 #define clr                clear
 35 #define pb                 push_back
 36 #define mp                 make_pair
 37 #define fir                first
 38 #define sec                second
 39 #define all(x)             (x).begin(),(x).end()
 40 #define SZ(x)             ((int)(x).size())
 41 #define lson            l, mid, rt<<1
 42 #define rson            mid+1, r, rt<<1|1
 43 
 44 typedef struct node_t {
 45     char s[20];
 46 
 47     node_t() {}
 48     node_t(int a[][4]) {
 49         int l = 0;
 50         rep(i, 0, 4)
 51             rep(j, 0, 4)
 52                 s[l++] = a[i][j]+'0';
 53         s[l] = '';
 54     }
 55 
 56     friend bool operator< (const node_t& a, const node_t& b) {
 57         return strcmp(a.s, b.s)<0 ? true:false;
 58     }
 59 
 60     friend bool operator== (const node_t& a, const node_t& b) {
 61         return strcmp(a.s, b.s)==0;
 62     }
 63 
 64     friend bool operator!= (const node_t& a, const node_t& b) {
 65         return strcmp(a.s, b.s)!=0;
 66     }
 67 
 68     void print() {
 69         for (int i=0; i<16; i+=4) {
 70             for (int j=0; j<4; ++j)
 71                 putchar(s[i+j]);
 72             putchar('
');
 73         }
 74     }
 75 
 76 } node_t;
 77 
 78 const int maxn = 10001;
 79 bool isPrime[maxn];
 80 bool valid[maxn];
 81 int a[maxn], an;
 82 int b[maxn], bn;
 83 int c[maxn], cn;
 84 bool M03[10][10];
 85 vector<node_t> ans;
 86 vi AV21[100];
 87 vi AV30[100];
 88 vi CV21[100];
 89 vi CV30[100];
 90 int M[4][4];
 91 
 92 void getV(int* a, int n, vi vc30[], vi vc21[]) {
 93     int d[4];
 94 
 95     rep(i, 0, n) {
 96         int x = a[i];
 97         rep(j, 0, 4) {
 98             d[j] = x % 10;
 99             x /= 10;
100         }
101         int v30 = d[3]*10+d[0];
102         int v21 = d[2]*10+d[1];
103         vc30[v30].pb(v21);
104         vc21[v21].pb(v30);
105     }
106 
107     vi::iterator iter;
108     rep(i, 0, 100) {
109         sort(all(vc30[i]));
110         iter = unique(all(vc30[i]));
111         vc30[i].erase(iter, vc30[i].end());
112 
113         sort(all(vc21[i]));
114         iter = unique(all(vc21[i]));
115         vc21[i].erase(iter, vc21[i].end());
116     }
117 }
118 
119 void init() {
120     int i, j, k;
121     int x;
122     int d[4];
123 
124     an = bn = cn = 0;
125     memset(isPrime, true, sizeof(isPrime));
126     memset(valid, false, sizeof(valid));
127     isPrime[0] = isPrime[1] = false;
128 
129     for (i=2; i<maxn; ++i) {
130         if (isPrime[i]) {
131             b[bn++] = i;
132             for (j=i*i; j<maxn; j+=i)
133                 isPrime[j] = false;
134         }
135     }
136 
137     memset(M03, false, sizeof(M03));
138     for (i=0; i<bn; ++i) {
139         x = b[i];
140         if (valid[x])
141             continue;
142         for (j=0; j<4; ++j) {
143             d[j] = x % 10;
144             x /= 10;
145         }
146         if ((d[0]&1)==0 || (d[3]&1)==0)
147             continue;
148         x = 0;
149         for (j=0; j<4; ++j) {
150             x = x * 10 + d[j];
151         }
152         if (isPrime[x]) {
153             valid[x] = valid[b[i]] = true;
154             a[an++] = x;
155             a[an++] = b[i];
156             M03[d[0]][d[3]] = M03[d[3]][d[0]] = true;
157             bool flag = true;
158             for (j=0; j<4; ++j) {
159                 if ((d[j] & 1)==0) {
160                     flag = false;
161                     break;
162                 }
163             }
164             if (flag) {
165                 c[cn++] = x;
166                 c[cn++] = b[i];
167             }
168         }
169     }
170 
171     sort(a, a+an);
172     an = unique(a, a+an) - a;
173     sort(c, c+cn);
174     cn = unique(c, c+cn) - c;
175 
176     getV(a, an, AV30, AV21);
177     getV(c, cn, CV30, CV21);
178 }
179 
180 void solve_() {
181     int v30 = 10*M[0][0]+M[3][3];
182     int v30_ = 10*M[0][3]+M[3][0];
183 
184     int sz = SZ(AV30[v30]);
185     int sz_ = SZ(AV30[v30_]);
186     rep(i, 0, sz) {
187         int v21 = AV30[v30][i];
188         M[1][1] = v21/10;
189         M[2][2] = v21%10;
190         rep(j, 0, sz_) {
191             int v21_ = AV30[v30_][j];
192             M[1][2] = v21_/10;
193             M[2][1] = v21_%10;
194 
195             int v1 = M[0][1]*1000+100*M[1][1]+M[2][1]*10+M[3][1];
196             int v2 = M[0][2]*1000+100*M[1][2]+M[2][2]*10+M[3][2];
197             int v3 = M[1][0]*1000+100*M[1][1]+M[1][2]*10+M[1][3];
198             int v4 = M[2][0]*1000+100*M[2][1]+M[2][2]*10+M[2][3];
199 
200             if (valid[v1] && valid[v2] && valid[v3] && valid[v4]) {
201                 ans.pb(node_t(M));
202             }
203         }
204     }
205 }
206 
207 void solve() {
208     int d1[4];
209     int d2[4];
210     int d3[4];
211 
212     rep(i, 0, cn) {
213         int x = c[i];
214         rep(dd, 0, 4) {
215             d1[dd] = x % 10;
216             x /= 10;
217         }
218         int f1 = d1[3];
219         int e1 = d1[0];
220         rep(j, 0, cn) {
221             int x = c[j];
222             rep(dd, 0, 4) {
223                 d2[dd] = x % 10;
224                 x /= 10;
225             }
226             int f2 = d2[3];
227             int e2 = d2[0];
228             if (f1 != f2)
229                 continue;
230             rep(k, 0, cn) {
231                 int x = c[k];
232                 rep(dd, 0, 4) {
233                     d3[dd] = x % 10;
234                     x /= 10;
235                 }
236                 int f3 = d3[3];
237                 int e3 = d3[0];
238                 if (f3 != e1)
239                     continue;
240 
241                 int v30 = e2*10 + e3;
242                 int sz_CV30 = SZ(CV30[v30]);
243                 rep(ii, 0, sz_CV30) {
244                     int v21 = CV30[v30][ii];
245                     int x3 = v21/10;
246                     int y3 = v21%10;
247 
248                     M[0][0] = d1[3];
249                     M[0][1] = d1[2];
250                     M[0][2] = d1[1];
251                     M[0][3] = d1[0];
252 
253                     M[1][0] = d2[2];
254                     M[2][0] = d2[1];
255                     M[3][0] = d2[0];
256 
257                     M[1][3] = d3[2];
258                     M[2][3] = d3[1];
259                     M[3][3] = d3[0];
260 
261                     M[3][1] = x3;
262                     M[3][2] = y3;
263                     
264                     solve_();
265                 }
266             }
267         }
268     }
269 }
270 
271 void print() {
272     sort(all(ans));
273     vector<node_t>::iterator iter = unique(all(ans));
274     ans.erase(iter, ans.end());
275     int sz = SZ(ans);
276     ans[0].print();
277     rep(i, 1, sz) {
278         putchar('
');
279         ans[i].print();
280     }
281 }
282 
283 int main() {
284     ios::sync_with_stdio(false);
285     #ifndef ONLINE_JUDGE
286         freopen("data.in", "r", stdin);
287         freopen("data.out", "w", stdout);
288     #endif
289 
290     init();
291     solve();
292     print();
293 
294     #ifndef ONLINE_JUDGE
295         printf("time = %d.
", (int)clock());
296     #endif
297 
298     return 0;
299 }
原文地址:https://www.cnblogs.com/bombe1013/p/5112978.html