USACO 6.4 The Primes

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

————————————————————————题解其实这又是一道搜索顺序至关重要的搜索题计算机比人脑强大的地方就是能做大量重复的复杂运算我们发现主对角线其实影响最大,然后是次对角线,然后逐渐再将限制较多的行或列填上,例如最后一行或者最后一列的数必须是1,3,7,9预处理出所有5位、各数位的和为n的素数。按照这样的搜索顺序1  4  6  5  28  1  7  2  810  4  1  5  109  2  7  1  92  3  3  3  1这样我们可以就可以少打几个循环了……在计算素数的时候同时求一些一些数位固定的数【其中XYZ为已知数,.为未知数,_ 为1,3,7,9】例如枚举1,X ... _枚举2,_ . X . _枚举3,X_ _ _ Y枚举4,5 .X . Y Z6可以直接计算枚举7 X . Y . Z枚举8,9 . X Y Z _10可以直接计算然后时限为2s的题就可以0.011过了
  1 /*
  2 LANG: C++
  3 PROG: prime3
  4 */
  5 #include <iostream>
  6 #include <cstdio>
  7 #include <algorithm>
  8 #include <cstring>
  9 #define siji(i,x,y) for(int i=(x); i<=(y) ; ++i)
 10 #define gongzi(j,x,y) for(int j=(x); j>=(y) ; --j)
 11 #define ivorysi
 12 using namespace std;
 13 int n,fi;
 14 int p[1005][6],sum,prime[50005],tot,all;
 15 bool noprime[100005];
 16 typedef struct {
 17     int l,r[200];
 18 }RECORD200;
 19 /*typedef struct {
 20     int l,r[50];
 21 }RECORD50;*/
 22 typedef struct {
 23     int l,r[20];
 24 }RECORD20;
 25 //.0-9 _ 1.3.7.9  - non-zero
 26 RECORD200 pat1[10];//X..._ 4*10*10
 27 RECORD200 pat2[10];//_.X._ 4*4*10
 28 RECORD20 pat3[10][10];//X___Y 4*4
 29 RECORD20 pat4[10][10][10];//-X.YZ 9
 30 RECORD20 pat7[10][10][10];//X.Y.Z 10
 31 RECORD20 pat8[10][10][10];//.XYZ_ 4
 32 string sol[1005];
 33 int marks[6][6];
 34 bool check(int x) {
 35     if(x%2==0 || x%5==0) return 0;
 36     return 1;
 37 }
 38 void makeprime() {
 39     siji(i,2,99999) {
 40         if(!noprime[i]) {
 41             prime[++tot]=i;
 42             if(i>10000) {
 43                 int temp=0;
 44                 for(int k=1;k<=10000;k*=10) {
 45                     temp+=i/k%10;
 46                 }
 47                 if(temp==n) {
 48                     ++sum;
 49                     for(int k=1,m=5;k<=10000 && m>=1;k*=10,--m) {
 50                         p[sum][m]=i/k%10;
 51                     }
 52                     int t1,t2,t3,t4,t5;
 53                     t1=p[sum][1],t2=p[sum][2],t3=p[sum][3],t4=p[sum][4],t5=p[sum][5];
 54                     pat1[t1].r[++pat1[t1].l]=sum;
 55                     if(check(t1)) pat2[t3].r[++pat2[t3].l]=sum;
 56                     if(check(t2)&&check(t3)&&check(t4)) {
 57                         pat3[t1][t5].r[++pat3[t1][t5].l]=sum;
 58                     }
 59                     pat4[t2][t4][t5].r[++pat4[t2][t4][t5].l]=sum;
 60                     pat7[t1][t3][t5].r[++pat7[t1][t3][t5].l]=sum;
 61                     pat8[t2][t3][t4].r[++pat8[t2][t3][t4].l]=sum;
 62                 }
 63             }
 64         }
 65         for(int j=1;j<=tot && i<100000/prime[j];++j) {
 66             noprime[prime[j]*i]=1;
 67             if(i%prime[j]==0) break;
 68         }
 69     }
 70 }
 71 void addsolution() {
 72     ++all;
 73     siji(i,1,5) {
 74         siji(j,1,5) {
 75             sol[all].append(1,marks[i][j]+‘0‘);
 76         }
 77     }
 78 }
 79 int num(int x) {
 80     int res=0;
 81     siji(i,1,5) res=res*10+p[x][i];
 82     return res;
 83 }
 84 void solve() {
 85     scanf("%d%d",&n,&fi);
 86     makeprime();
 87     int us,tj,tk,tm,tw,ty,tx,tq,temp,temp1,temp2;
 88     for(int i=1;i<=pat1[fi].l;++i) {
 89         memset(marks,0,sizeof(marks));
 90         us=pat1[fi].r[i];
 91         siji(iv,1,5) marks[iv][iv]=p[us][iv];
 92         tj=pat2[marks[3][3]].l;
 93         for(int j=1;j<=tj;++j) {
 94             us=pat2[marks[3][3]].r[j];
 95             siji(iv,1,5) marks[5-iv+1][iv]=p[us][iv];
 96             tk=pat3[marks[5][1]][marks[5][5]].l;
 97             for(int k=1;k<=tk;++k) {
 98                 us=pat3[marks[5][1]][marks[5][5]].r[k];
 99                 siji(iv,2,4) marks[5][iv]=p[us][iv];
100                 tm=pat4[marks[2][2]][marks[4][2]][marks[5][2]].l;
101                 for(int m=1;m<=tm;++m) {
102                     us=pat4[marks[2][2]][marks[4][2]][marks[5][2]].r[m];
103                     marks[1][2]=p[us][1];
104                     marks[3][2]=p[us][3];
105                     tw=pat4[marks[2][4]][marks[4][4]][marks[5][4]].l;
106                     for(int w=1;w<=tw;++w) {
107                         us=pat4[marks[2][4]][marks[4][4]][marks[5][4]].r[w];
108                         marks[1][4]=p[us][1];
109                         marks[3][4]=p[us][3];
110                         marks[1][3]=0;
111                         temp=0;
112                         siji(iv,1,5) temp+=marks[1][iv];
113                         marks[1][3]=n-temp;
114                         if(marks[1][3]<1 || marks[1][3]>9) continue;
115                         temp=0;
116                         siji(iv,1,5) {
117                             temp=temp*10+marks[1][iv];
118                         }
119                         if(noprime[temp]) continue;
120                         ty=pat7[marks[1][3]][marks[3][3]][marks[5][3]].l;
121                         for(int y=1;y<=ty;++y) {
122                             us=pat7[marks[1][3]][marks[3][3]][marks[5][3]].r[y];
123                             marks[2][3]=p[us][2];
124                             marks[4][3]=p[us][4];
125                             tx=pat8[marks[2][2]][marks[2][3]][marks[2][4]].l;
126                             for(int x=1;x<=tx;++x) {
127                                 us=pat8[marks[2][2]][marks[2][3]][marks[2][4]].r[x];
128                                 marks[2][1]=p[us][1];
129                                 marks[2][5]=p[us][5];
130                                 tq=pat8[marks[4][2]][marks[4][3]][marks[4][4]].l;
131                                 for(int q=1;q<=tq;++q) {
132                                     us=pat8[marks[4][2]][marks[4][3]][marks[4][4]].r[q];
133                                     marks[4][1]=p[us][1];
134                                     marks[4][5]=p[us][5];
135                                     marks[3][1]=marks[3][5]=0;
136                                     temp1=temp2=0;
137                                     siji(iv,1,5) temp1+=marks[iv][1],temp2+=marks[iv][5];
138                                     marks[3][1]=n-temp1;marks[3][5]=n-temp2;
139                                     if(marks[3][1]<1 || marks[3][5]<1 ||marks[3][1]>9 || marks[3][5]>9)
140                                         continue;
141                                     temp1=temp2=0;
142                                     siji(iv,1,5)
143                                         temp1=temp1*10+marks[iv][1],temp2=temp2*10+marks[iv][5];
144                                     if(noprime[temp1]||noprime[temp2]) continue;
145                                     temp1=temp2=0;
146                                     siji(iv,1,5)
147                                         temp1=temp1*10+marks[3][iv],temp2+=marks[3][iv];
148                                     if(noprime[temp1] || temp2!=n) continue;
149                                     addsolution();
150                                 }
151                             }
152                         }
153                     }
154                 }
155             }
156         }
157     }
158     if(all==0) puts("NONE");
159     sort(sol+1,sol+all+1);
160     siji(i,1,all) {
161         for(int j=0;j<5;++j) {
162             cout<<sol[i].substr(j*5,5)<<endl;
163         }
164         if(i!=all) puts("");
165     }
166 }
167 int main(int argc, char const *argv[])
168 {
169 #ifdef ivorysi
170     freopen("prime3.in","r",stdin);
171     freopen("prime3.out","w",stdout);
172 #else
173     freopen("f1.in","r",stdin);
174     freopen("f1.out","w",stdout);
175 #endif
176     solve();
177     return 0;
178 }
 
时间: 2024-12-11 13:53:43

USACO 6.4 The Primes的相关文章

[USACO 6.4.1] The Primes

题目大意 给一个5*5的矩阵,在每个格子里面填入0~9这10个数字.要求行从左往右读,列从上往下读,两条对角线从上往下读是一个5位素数且不含前导0. 现在给出了开头的数字和行,列,对角线之和,求符合规定的所有数字矩阵. 题解 这是一道搜索题. 但盲目的搜索是会TLE的.因此,我们应当采用合理的剪枝. 由题目可知,加入行列对角线我们知道了任意4位数,我们可以推出第5位数是什么. 因此,我们可以采用传说中的手动指定搜索顺序的方法来搜索和回溯. 具体搜索顺序如下图. 大概就是这样的感觉. 里面的C是可

算法竞赛入门经典+挑战编程+USACO

下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发.   一.UVaOJ http://uva.onlinejudge.org  西班牙Valladolid大学的程序在线评测系统,是历史最悠久.最著名的OJ.   二.<算法竞赛入门经典> 刘汝佳  (UVaOJ  351道题)  以下部分内容摘自:http://sdkdacm.5d6d.com/thread-6-1-1.html   "AO

(Step1-500题)UVaOJ+算法竞赛入门经典+挑战编程+USACO

下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发. 一.UVaOJ http://uva.onlinejudge.org 西班牙Valladolid大学的程序在线评测系统,是历史最悠久.最著名的OJ. 二.<算法竞赛入门经典> 刘汝佳  (UVaOJ  351道题)  以下部分内容摘自:http://sdkdacm.5d6d.com/thread-6-1-1.html “AOAPC I”是刘汝佳(大

COGS 696. [IOI1996][USACO 2.3] 最长前缀

★   输入文件:prefix.in   输出文件:prefix.out   简单对比时间限制:1 s   内存限制:128 MB 描述 USACO 2.3.1 IOI96 在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的.生物学家对于把长的序列分解成较短的序列(即元素)很感兴趣. 如果一个集合 P 中的元素可以通过串联(元素可以重复使用,相当于 Pascal 中的 “+” 运算符)组成一个序列 S ,那么我们认为序列 S 可以分解为 P 中的元素.元素不一定要全部出现(如下例中B

[LeetCode]Count Primes

题目:Count Primes 统计1-n的素数的个数. 思路1: 通常的思想就是遍历(0,n)范围内的所有数,对每个数i再遍历(0,sqrt(i)),每个除一遍来判断是否为素数,这样时间复杂度为O(n*sqrt(n)). 具体实现不在贴代码,过程很简单,两重循环就可以解决.但是效率很差,n较大时甚至会花几分钟才能跑完. 思路2: 用埃拉特斯特尼筛法的方法来求素数,时间复杂度可以达到O(nloglogn). 首先开一个大小为n的数组prime[],从2开始循环,找到一个质数后开始筛选出所有非素数

projecteuler Summation of primes

The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17. Find the sum of all the primes below two million. 译文: 10以下的素数之和为17,求出2000000以下的素数之和. ======================= 第一次code: 1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(

USACO prefix TrieTree + DP

/* ID:kevin_s1 PROG:prefix LANG:C++ */ #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <vector> #include <map> #include <set> #include <algorithm> #include <cstdlib>

【USACO 1.3.4】牛式

[題目描述 ] 下面是一个乘法竖式,如果用我们给定的那n个数字来取代*,可以使式子成立的话,我们就叫这个式子牛式. * * * x * * ---------- * * * * * * ---------- * * * * 数字只能取代*,当然第一位不能为0,况且给定的数字里不包括0. 注意一下在美国的学校中教的"部分乘积",第一部分乘积是第二个数的个位和第一个数的积,第二部分乘积是第二个数的十位和第一个数的乘积. 写一个程序找出所有的牛式. [格式] INPUT FORMAT: (f

USACO Chapter 1 Section 1.1

USACO的题解和翻译已经很多了... 我只是把自己刷的代码保存一下. 1.PROB Your Ride Is Here 1 /* 2 ID:xiekeyi1 3 PROG:ride 4 LANG:C++ 5 */ 6 7 #include<bits/stdc++.h> 8 using namespace std ; 9 10 int main() 11 { 12 freopen("ride.in","r",stdin); 13 freopen(&quo