USACO6.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
题目大意:给出一个5*5的正方形和左上角的一个数字,要求每一行每一列每一对角线上的数字的和都等于输入的数,并且组成的五位数为质数,输出所有可能的5*5正方形。 算法:这是一道很麻烦的暴力题,朴素的枚举必定会超时,这时候需要调换枚举顺序,以及根据枚举的五位数的位置尽可能排除不可能的情况再枚举,要优化的地方还是比较多的,详见代码。
#include <iostream>
#include <memory.h>
#include <stdio.h>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
#define MAXN 100000
#define R 0
#define C 1 void output(string str)
{
for(int i=; i<str.length(); i++)
{
printf("%c",str[i]);
if(i%==)
printf("\n");
}
} int getDigSum(int x)
{
int sum=;
while(x!=)
{
sum+=x%;
x/=;
}
return sum;
} bool allDigOdd(int x)
{
while(x!=)
{
int dig=x%;
if(dig%==)
return false;
x/=;
}
return true;
} bool allNoZero(int x)
{
while(x!=)
{
int dig=x%;
if(dig==)
return false;
x/=;
}
return true;
} int isPrime[MAXN+],primeDig[MAXN+][]; int a[][]= {},goalSum=,st;
vector<int> primelist[]; // 以d[ij]表示以i开头,j结尾的字符串
vector<int> primelistMid[]; // 以d[ijk]表示以i开头,j为百位,k结尾的字符串
vector<int> primelistOdd[]; // 各位上的数都为奇数
vector<int> primelistnozero[]; // 各位上都没有0
vector<string> res; int isprime(int type,int num)
{ int sum=;
if(type==R)
{
for(int i=; i<; i++)
sum=sum*+a[num][i];
}
else
{
for(int i=; i<; i++)
sum=sum*+a[i][num];
}
return isPrime[sum];
} void add()
{
string str;
for(int i=; i<; i++)
for(int j=; j<; j++)
{
str+=''+a[i][j];
}
res.push_back(str);
} void initA()
{
for(int i=; i<; i++)
for(int j=; j<; j++)
a[i][j]=;
} int main()
{
freopen("prime3.in","r",stdin);
freopen("prime3.out","w",stdout); initA(); // 求素数表
memset(isPrime,-,sizeof isPrime);
for(int i=; i<=MAXN; i++)
if(isPrime[i])
for(long long j=(long long)i*i; j<=MAXN; j+=i)
isPrime[j]=false; cin>>goalSum>>st; for(int i=; i<MAXN; i++)
if(isPrime[i] && getDigSum(i)!=goalSum)
isPrime[i]=; for(int i=; i<MAXN; i++)
if(isPrime[i])
{
int x=i;
for(int j=; j<; j++)
{
primeDig[i][-j]=x%;
x/=;
}
primelist[i/*+i%].push_back(i);
primelistMid[i/*+(i%)/*+i%].push_back(i);
} // 各位上都为奇数
for(int i=; i<MAXN; i++)
if(isPrime[i] && allDigOdd(i))
primelistOdd[i/*+i%].push_back(i); // 各位上都为非0
for(int i=; i<MAXN; i++)
if(isPrime[i] && allNoZero(i))
primelistnozero[i/*+i%].push_back(i); bool found=false; a[][]=st;
// 枚举 先是右下方数字
for(a[][]=; a[][]<=; a[][]+=)
{
// 枚举左下方数字
for(a[][]=; a[][]<=; a[][]+=)
{
// 枚举右上方数字
for(a[][]=; a[][]<=; a[][]+=)
{
//填充左边质数
for(int i=; i<primelistnozero[st*+a[][]].size(); i++)
{
for(int j=; j<; j++)
a[j][]=primeDig[primelistnozero[st*+a[][]][i]][j]; // 填充上边质数
for(int ii=; ii<primelistnozero[st*+a[][]].size(); ii++)
{
for(int j=; j<; j++)
a[][j]=primeDig[primelistnozero[st*+a[][]][ii]][j]; // 填充下边质数
for(int iii=; iii<primelistOdd[a[][]*+a[][]].size(); iii++)
{
for(int j=; j<; j++)
a[][j]=primeDig[primelistOdd[a[][]*+a[][]][iii]][j]; //填充右边质数
for(int iiii=; iiii<primelistOdd[a[][]*+a[][]].size(); iiii++)
{
for(int j=; j<; j++)
a[j][]=primeDig[primelistOdd[a[][]*+a[][]][iiii]][j]; // 填充中间一点
for(a[][]=; a[][]<=; a[][]++)
{ // 填充主对角线
for(int k=; k<primelistMid[st*+a[][]*+a[][]].size(); k++)
{
a[][]=primeDig[primelistMid[st*+a[][]*+a[][]][k]][];
a[][]=primeDig[primelistMid[st*+a[][]*+a[][]][k]][]; // 填充辅对角线
for(int l=; l<primelistMid[a[][]*+a[][]*+a[][]].size(); l++)
{
a[][]=primeDig[primelistMid[a[][]*+a[][]*+a[][]][l]][];
a[][]=primeDig[primelistMid[a[][]*+a[][]*+a[][]][l]][]; int a12=goalSum-(a[][]+a[][]+a[][]+a[][]);
int a21=goalSum-(a[][]+a[][]+a[][]+a[][]);
int a23=goalSum-(a[][]+a[][]+a[][]+a[][]);
int a32=goalSum-(a[][]+a[][]+a[][]+a[][]);
a[][]=a12;
a[][]=a21;
a[][]=a23;
a[][]=a32;
if(a12>= && a12< && a21>= && a21< && a23>= && a23< && a32>= && a32<
&& isprime(R,) && isprime(R,) && isprime(R,)
&& isprime(C,) && isprime(C,) && isprime(C,))
{
found=true;
add();
}
} }
} }
}
}
}
}
}
} sort(res.begin(),res.end());
bool first=true;
for(int i=; i<res.size(); i++)
{
if(!first)
{
cout<<endl;
}
first=false;
output(res[i]);
} if(!found)
printf("NONE\n");
return ;
}
USACO6.4-The Primes的更多相关文章
- [LeetCode] Count Primes 质数的个数
Description: Count the number of prime numbers less than a non-negative number, n click to show more ...
- 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 milli ...
- leetcode-Count Primes 以及python的小特性
题目大家都非常熟悉,求小于n的所有素数的个数. 自己写的python 代码老是通不过时间门槛,无奈去看了看大家写的code.下面是我看到的投票最高的code: class Solution: # @p ...
- Count Primes - LeetCode
examination questions Description: Count the number of prime numbers less than a non-negative number ...
- [leetcode] Count Primes
Count Primes Description: Count the number of prime numbers less than a non-negative number, n click ...
- Count Primes
Count the number of prime numbers less than a non-negative number, n public int countPrimes(int n) { ...
- hduoj 4715 Difference Between Primes 2013 ACM/ICPC Asia Regional Online —— Warmup
http://acm.hdu.edu.cn/showproblem.php?pid=4715 Difference Between Primes Time Limit: 2000/1000 MS (J ...
- HDU 4715:Difference Between Primes
Difference Between Primes Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav ...
- hdu 4715 Difference Between Primes
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4715 Difference Between Primes Description All you kn ...
随机推荐
- 二分图的最大匹配-hdu-3729-I'm Telling the Truth
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3729 题目意思: 有n个学生,老师询问每个学生的排名,每个学生都告诉了一个排名区间,求可能的最多的学 ...
- 国内三大PT(Private Tracker)站分析
除这一行外,下面全部内容都是转载.出处不明. 国内三大PT(Private Tracker)站分析 先郑重的声明一下:本文以下的内容所有是复制粘贴的,不代表老夫的观点. 事实上内容我也没细致看. 贴这 ...
- 你真的了解 console 吗
对于前端开发者来说,在开发过程中需要监控某些表达式或变量的值的时候,用 debugger 会显得过于笨重,取而代之则是会将值输出到控制台上方便调试.最常用的语句就是console.log(expres ...
- 手机端input,select屏蔽浏览器默认事件
文本框input:当文本框focus时会弹出软键盘,有时我们需要click事件而又不想触发focus事件(不要弹出软键盘) 给input添加 disabled="disabled" ...
- (转)TortoiseSVN使用简介
TortoiseSVN使用简介 TortoiseSVN使用简介 2009-04-24 来源:dev.idv.tw 1 安装及下载client 端 2 什么是SVN(Subversion)? 3 为甚么 ...
- 3.RxJava详解
一.RxJava 到底是什么 异步(取代AsyncTask/Handler/XXX/...?) 二.RxJava 好在哪 简洁(逻辑的简洁,.一步一走) 举例: 题目:将文件夹中的图片都取 ...
- 25 读取jar包内log4j.properties文件方法
//读取log4j日志配置文件 InputStream inputStream=ApplicationExecutor.class.getResourceAsStream("/log4j_h ...
- java事件处理5(窗口,窗口坐监视器
WindowEvent窗口事件 添加接口 addWindowListener(WindowEvent e) 接口有七个方法 public void windowActivated(WindowEven ...
- C/C++默认浮点型
代码: #include <iostream> #include <cstdio> using namespace std; void test(int a){ cout< ...
- Linux "top" 命令解析
TOP命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况. TOP是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户 ...