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 ...
随机推荐
- Robotium -- 针对apk包的测试
在使用Robotium测试的时候,有时候,测试人员并没有代码权限,而Robotium也可以在只有apk文件进行测试,下面就介绍一下这个过程. 1.设置环境变量 安装jdk环境和sdk环境 2.安装签名 ...
- [Angular 2] Child Router
Benefit to use child router is Angualr 2 then can lazy load the component on demand. Define a child ...
- Zend框架2入门(一) (转)
By Rob Allen, www.akrabat.com 修订0.1.2文件版权所有? 2011本教程的目的是给创建一个简单的数据库的介绍使用Zend Framework 2驱动的应用程序使用模型 ...
- C++ TinyXml操作(含源码下载)
前言 TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译,使用TinyXML进行C++ XML解析,使用简单,容易上手.这个解析库的模型通过解析X ...
- TCP/IP协议原理与应用笔记05:TCP/IP协议下的网关
大家都知道,从一个房间走到另一个房间,必然要经过一扇门.同样,从一个网络向另一个网络发送信息,也必须经过一道“关口”,这道关口就是网关.顾名思义,网关(Gateway)就是一个网络连接到另一个网络的& ...
- linux常见设备类型及文件系统
As you can see in Table 14.3 , all disk device names end with the letter a. That is because it ...
- SQL语句添加删除修改字段及一些表与字段的基本操作
用SQL语句添加删除修改字段 1.增加字段 alter table docdsp add dspcode char(200)2.删除字段 ALTER TABLE table_NA ...
- CSS3 字体
CSS3 @font-face 规则 在 CSS3 之前,web 设计师必须使用已在用户计算机上安装好的字体. 通过 CSS3,web 设计师可以使用他们喜欢的任意字体. 当您您找到或购买到希望使用的 ...
- GDI+基础(2)
使用钢笔,画笔用来填充图形内部,钢笔则用来绘制带有一定宽度,样式和色彩的线条和曲线. 可以使用标准的pens类 <%@ Page ContentType="image/gif" ...
- ViewPager Indicator的使用方法
原文:http://my.oschina.net/u/1403288/blog/208402 项目源码:https://github.com/wangjing0311/ViewPagerIndicat ...