标签:style blog io ar color os sp for strong
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 | +---+---+---+---+---+
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.
11 1
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".
The above example has 3 solutions.
11351 14033 30323 53201 13313 11351 33203 30323 14033 33311 13313 13043 32303 50231 13331
题目大意:给出一个5*5的正方形和左上角的一个数字,要求每一行每一列每一对角线上的数字的和都等于输入的数,并且组成的五位数为质数,输出所有可能的5*5正方形。
算法:这是一道很麻烦的暴力题,朴素的枚举必定会超时,这时候需要调换枚举顺序,以及根据枚举的五位数的位置尽可能排除不可能的情况再枚举,要优化的地方还是比较多的,详见代码。
1 #include <iostream> 2 #include <memory.h> 3 #include <stdio.h> 4 #include <vector> 5 #include <string> 6 #include <algorithm> 7 using namespace std; 8 #define MAXN 100000 9 #define R 0 10 #define C 1 11 12 13 void output(string str) 14 { 15 for(int i=0; i<str.length(); i++) 16 { 17 printf("%c",str[i]); 18 if(i%5==4) 19 printf("\n"); 20 } 21 } 22 23 int getDigSum(int x) 24 { 25 int sum=0; 26 while(x!=0) 27 { 28 sum+=x%10; 29 x/=10; 30 } 31 return sum; 32 } 33 34 bool allDigOdd(int x) 35 { 36 while(x!=0) 37 { 38 int dig=x%10; 39 if(dig%2==0) 40 return false; 41 x/=10; 42 } 43 return true; 44 } 45 46 bool allNoZero(int x) 47 { 48 while(x!=0) 49 { 50 int dig=x%10; 51 if(dig==0) 52 return false; 53 x/=10; 54 } 55 return true; 56 } 57 58 int isPrime[MAXN+10],primeDig[MAXN+10][5]; 59 60 int a[5][5]= {0},goalSum=0,st; 61 vector<int> primelist[100]; // 以d[ij]表示以i开头,j结尾的字符串 62 vector<int> primelistMid[1000]; // 以d[ijk]表示以i开头,j为百位,k结尾的字符串 63 vector<int> primelistOdd[100]; // 各位上的数都为奇数 64 vector<int> primelistnozero[100]; // 各位上都没有0 65 vector<string> res; 66 67 int isprime(int type,int num) 68 { 69 70 int sum=0; 71 if(type==R) 72 { 73 for(int i=0; i<5; i++) 74 sum=sum*10+a[num][i]; 75 } 76 else 77 { 78 for(int i=0; i<5; i++) 79 sum=sum*10+a[i][num]; 80 } 81 return isPrime[sum]; 82 } 83 84 void add() 85 { 86 string str; 87 for(int i=0; i<5; i++) 88 for(int j=0; j<5; j++) 89 { 90 str+=‘0‘+a[i][j]; 91 } 92 res.push_back(str); 93 } 94 95 void initA() 96 { 97 for(int i=0; i<5; i++) 98 for(int j=0; j<5; j++) 99 a[i][j]=100; 100 } 101 102 int main() 103 { 104 freopen("prime3.in","r",stdin); 105 freopen("prime3.out","w",stdout); 106 107 initA(); 108 109 // 求素数表 110 memset(isPrime,-1,sizeof isPrime); 111 for(int i=2; i<=MAXN; i++) 112 if(isPrime[i]) 113 for(long long j=(long long)i*i; j<=MAXN; j+=i) 114 isPrime[j]=false; 115 116 117 cin>>goalSum>>st; 118 119 for(int i=10000; i<MAXN; i++) 120 if(isPrime[i] && getDigSum(i)!=goalSum) 121 isPrime[i]=0; 122 123 for(int i=10000; i<MAXN; i++) 124 if(isPrime[i]) 125 { 126 int x=i; 127 for(int j=0; j<5; j++) 128 { 129 primeDig[i][4-j]=x%10; 130 x/=10; 131 } 132 primelist[i/10000*10+i%10].push_back(i); 133 primelistMid[i/10000*100+(i%1000)/100*10+i%10].push_back(i); 134 } 135 136 // 各位上都为奇数 137 for(int i=10000; i<MAXN; i++) 138 if(isPrime[i] && allDigOdd(i)) 139 primelistOdd[i/10000*10+i%10].push_back(i); 140 141 // 各位上都为非0 142 for(int i=10000; i<MAXN; i++) 143 if(isPrime[i] && allNoZero(i)) 144 primelistnozero[i/10000*10+i%10].push_back(i); 145 146 bool found=false; 147 148 a[0][0]=st; 149 // 枚举 先是右下方数字 150 for(a[4][4]=1; a[4][4]<=9; a[4][4]+=2) 151 { 152 // 枚举左下方数字 153 for(a[4][0]=1; a[4][0]<=9; a[4][0]+=2) 154 { 155 // 枚举右上方数字 156 for(a[0][4]=1; a[0][4]<=9; a[0][4]+=2) 157 { 158 //填充左边质数 159 for(int i=0; i<primelistnozero[st*10+a[4][0]].size(); i++) 160 { 161 for(int j=0; j<5; j++) 162 a[j][0]=primeDig[primelistnozero[st*10+a[4][0]][i]][j]; 163 164 // 填充上边质数 165 for(int ii=0; ii<primelistnozero[st*10+a[0][4]].size(); ii++) 166 { 167 for(int j=0; j<5; j++) 168 a[0][j]=primeDig[primelistnozero[st*10+a[0][4]][ii]][j]; 169 170 171 // 填充下边质数 172 for(int iii=0; iii<primelistOdd[a[4][0]*10+a[4][4]].size(); iii++) 173 { 174 for(int j=0; j<5; j++) 175 a[4][j]=primeDig[primelistOdd[a[4][0]*10+a[4][4]][iii]][j]; 176 177 178 //填充右边质数 179 for(int iiii=0; iiii<primelistOdd[a[0][4]*10+a[4][4]].size(); iiii++) 180 { 181 for(int j=0; j<5; j++) 182 a[j][4]=primeDig[primelistOdd[a[0][4]*10+a[4][4]][iiii]][j]; 183 184 185 // 填充中间一点 186 for(a[2][2]=0; a[2][2]<=9; a[2][2]++) 187 { 188 189 // 填充主对角线 190 for(int k=0; k<primelistMid[st*100+a[2][2]*10+a[4][4]].size(); k++) 191 { 192 a[1][1]=primeDig[primelistMid[st*100+a[2][2]*10+a[4][4]][k]][1]; 193 a[3][3]=primeDig[primelistMid[st*100+a[2][2]*10+a[4][4]][k]][3]; 194 195 // 填充辅对角线 196 for(int l=0; l<primelistMid[a[4][0]*100+a[2][2]*10+a[0][4]].size(); l++) 197 { 198 a[3][1]=primeDig[primelistMid[a[4][0]*100+a[2][2]*10+a[0][4]][l]][1]; 199 a[1][3]=primeDig[primelistMid[a[4][0]*100+a[2][2]*10+a[0][4]][l]][3]; 200 201 int a12=goalSum-(a[1][0]+a[1][1]+a[1][3]+a[1][4]); 202 int a21=goalSum-(a[0][1]+a[1][1]+a[3][1]+a[4][1]); 203 int a23=goalSum-(a[0][3]+a[1][3]+a[3][3]+a[4][3]); 204 int a32=goalSum-(a[3][0]+a[3][1]+a[3][3]+a[3][4]); 205 a[1][2]=a12; 206 a[2][1]=a21; 207 a[2][3]=a23; 208 a[3][2]=a32; 209 if(a12>=0 && a12<10 && a21>=0 && a21<10 && a23>=0 && a23<10 && a32>=0 && a32<10 210 && isprime(R,1) && isprime(R,2) && isprime(R,3) 211 && isprime(C,1) && isprime(C,2) && isprime(C,3)) 212 { 213 found=true; 214 add(); 215 } 216 } 217 218 } 219 } 220 221 } 222 } 223 } 224 } 225 } 226 } 227 } 228 229 sort(res.begin(),res.end()); 230 bool first=true; 231 for(int i=0; i<res.size(); i++) 232 { 233 if(!first) 234 { 235 cout<<endl; 236 } 237 first=false; 238 output(res[i]); 239 } 240 241 if(!found) 242 printf("NONE\n"); 243 return 0; 244 }
标签:style blog io ar color os sp for strong
原文地址:http://www.cnblogs.com/oneshot/p/4121954.html