【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] = '\0'; 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('\n'); 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('\n'); 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.\n", (int)clock()); 296 #endif 297 298 return 0; 299 }