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的更多相关文章

  1. [LeetCode] Count Primes 质数的个数

    Description: Count the number of prime numbers less than a non-negative number, n click to show more ...

  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 milli ...

  3. leetcode-Count Primes 以及python的小特性

    题目大家都非常熟悉,求小于n的所有素数的个数. 自己写的python 代码老是通不过时间门槛,无奈去看了看大家写的code.下面是我看到的投票最高的code: class Solution: # @p ...

  4. Count Primes - LeetCode

    examination questions Description: Count the number of prime numbers less than a non-negative number ...

  5. [leetcode] Count Primes

    Count Primes Description: Count the number of prime numbers less than a non-negative number, n click ...

  6. Count Primes

    Count the number of prime numbers less than a non-negative number, n public int countPrimes(int n) { ...

  7. 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 ...

  8. HDU 4715:Difference Between Primes

    Difference Between Primes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  9. hdu 4715 Difference Between Primes

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4715 Difference Between Primes Description All you kn ...

随机推荐

  1. Android SwitchButton(滑动开关)

    @RemoteView public class Button extends TextView { public Button(Context context) { this(context, nu ...

  2. VS2010 使用TeeChart画图控件 - 之二 - 绘制图形(折线图,柱状图)

    1.前期准备 详细可见VS2010 使用TeeChart画图控件 - 之中的一个 控件和类的导入 1. 1 加入TeeChart控件,给控件加入变量m_TeeChart 加入TeeChart控件,右击 ...

  3. [转] 在 Linux 中怎样使用cp命令合并目录树

    PS:通过cp -r --link a/* b/* merged 硬链接不需要复制 怎样将两个布局相似的目录树合并成一个新的目录树?为理解该问题让我们思考下面的例子. 假设 dir1 和 dir2 目 ...

  4. IO-文件 File 复制 读写 总结

    一定要注意: 传入的参数,应该是包含文件名的完整路径名,不能把一个文件复制到[文件夹]中,因为[文件夹]本身是不能有输入输出流的,只能复制到一个[文件]中,否则会报异常. 以字节流读写的三种方式 pu ...

  5. HTML基本概念

    什么是 HTML? HTML 是用来描述网页的一种语言. HTML 指的是超文本标记语言 (Hyper Text Markup Language) HTML 不是一种编程语言,而是一种标记语言 (ma ...

  6. vs连接mysql

    1.打开vs2012在aspx中添加一个Grid view 控件,,. 2,选择新建数据源. 3,选择数据库. 4,选择新建连接. 5,更改成mysql连接. 6,这里的Server name 是你自 ...

  7. Topshelf

    Topshelf允许开发者创建一个简单的控制台程序,将其安装为一个window服务. 这样做的原因很简单:方便调试. 使用命令行工具可以很方面的安装Topshelf创建的服务. server.exe ...

  8. Asp.Net WebApi Action命名中已‘Get’开头问题

    ApiController 中的Action 命名已‘Get’开头,Post方法提交失败 场景: 1.action命名使用Get开头 /// <summary> /// 获取用户的未读消息 ...

  9. ruby 知识点

    $LOAD_PATH 执行 require 读取文件时搜索的目录名数组,也可以写作 $: 创建 URI 的时候可以直接这样 URI("http://www.dy2018.com/i/9751 ...

  10. [c#]asp.net开发微信公众平台(1)数据库设计

    开发微信公众平台之前,先去微信官方了解下大概的情况 这里:http://mp.weixin.qq.com/wiki/index.php :看了之后心里大致有数了,开始设计数据库,尽可能的考虑,未考虑到 ...