luogu P1549 棋盘问题(2) 题解

题目描述

在\(N * N\)的棋盘上\((1≤N≤10)\),填入\(1,2,…,N^2\)共\(N^2\)个数,使得任意两个相邻的数之和为素数。

例如:当\(N=2\)时,有:

其相邻数的和为素数的有:

\(1+2,1+4,4+3,2+3\)

当\(N=4\)时,一种可以填写的方案如下:

在这里我们约定:左上角的格子里必须填数字\(1\)。

输入输出格式

输入格式:

一个数\(N\)

输出格式:

如有多种解,则输出第一行、第一列之和为最小的排列方案;若无解,则输出“NO”。

输入输出样例

输入样例#1:

1

输出样例#1:

NO

输入样例#2:

2

输出样例#2:

1 2

4 3

思路

看这数据这么小\((1≤N≤10)\),所以可以dfs。

但是dfs直接跑一下一定是不行的。所以,可以发现题面的要求:输出第一行、第一列之和为最小的排列方案。

那么怎样使它最小呢?

很简单,只要在第一行、第一列dfs的枚举时,\(i\)枚举顺序为\(1~n^2\),而不是第一行、第一列的其他数字则要取最大值,即枚举顺序为\(n^2~1\)(down to)。

然后就是dfs了啊。。。

素数怎么判断呢??

预处理一下200之内的素数,然后用桶判断一下就好了呀。

ps:素数判断可以直接只判断dfs的左、上之和(已经搜索了的数)与之和是不是素数就好了。

下附代码:

#include<algorithm>
#include<bitset>
#include<complex>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<iterator>
#include<limits>
#include<list>
#include<locale>
#include<map>
#include<memory>
#include<new>
#include<numeric>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<typeinfo>
#include<utility>
#include<valarray>
#include<vector>
#include<cstring>
#include<cmath>
#define ll long long
#define eps 1e-4
using namespace std;
//priority_queue<int,vector<int>,greater<int> > q1;
//priority_queue<int> q2;
//set<int> s;
//list<int> l;
//map<int> mp;
inline int read(){
int ret=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-f;ch=getchar();}
while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
inline void write(int zx){
if(zx<0){zx=-zx;putchar('-');}
if(zx<10) putchar(zx+'0');
else{
write(zx/10);
putchar(zx%10+'0');
}
}
int n;
int f[15][15],ans;
int prime[500];
bool used[500];
bool check(int zx){
for(int i=2;i<=sqrt(zx);i++)
if(zx%i==0) return 0;
return 1;
}
void print(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
write(f[i][j]);putchar(' ');
}
putchar('\n');
}
}
void dfs(int x,int y){
if(x==n&&y==n+1){
ans=1;
print();
exit(0);
}
if(f[x][y]!=0) return ;
if(y==n+1){
dfs(x+1,1);
return ;
}
int from=-1;
if(x==1||y==1){
for(int i=2;i<=n*n;i++){
if(used[i]==1) continue ;
if(x==1&&prime[f[x][y-1]+i]==0) continue ;
if(y==1&&prime[f[x-1][y]+i]==0) continue ;
f[x][y]=i;used[i]=1;
dfs(x,y+1);
f[x][y]=0;used[i]=0;
}
}else{
for(int i=n*n;i>=2;i--){
if(used[i]==1) continue ;
if(prime[f[x][y-1]+i]==0) continue ;
if(prime[f[x-1][y]+i]==0) continue ;
f[x][y]=i;used[i]=1;
dfs(x,y+1);
f[x][y]=0;used[i]=0;
}
}
}
int main(){
n=read();
if(n==1){
puts("NO");
return 0;
}
for(int i=2;i<=500;i++)
if(check(i)==1) prime[i]=1;
f[1][1]=1;used[1]=1;
dfs(1,2);
puts("NO");
return 0;
}

luogu P1549 棋盘问题(2) 题解的更多相关文章

  1. Luogu P1549 棋盘问题(2)

    题意 在N×N的棋盘上(1≤N≤10),填入1,2,-,N^2,共N^2个数,使得任意两个相邻的数之和为素数. 思路 先线性筛(非标准版),然后用a数组记录以i为下标的数是不是质数(就是标记数组),然 ...

  2. luogu P1126 机器人搬重物 题解

    luogu P1126 机器人搬重物 题解 题目描述 机器人移动学会(\(RMI\))现在正尝试用机器人搬运物品.机器人的形状是一个直径\(1.6\)米的球.在试验阶段,机器人被用于在一个储藏室中搬运 ...

  3. luogu 1169 棋盘制作(单调栈/悬线)

    luogu 1169 棋盘制作(单调栈/悬线) 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑白相间的方阵,对应 ...

  4. 洛谷P1549 棋盘问题(2)

    P1549 棋盘问题(2) 题目描述 在N*N的棋盘上(1≤N≤10),填入1,2,…,N*N共N*N个数,使得任意两个相邻的数之和为素数. 例如:当N=2时,有: 其相邻数的和为素数的有: 1+2, ...

  5. 洛谷——P1549 棋盘问题(2)

    P1549 棋盘问题(2) 搜索||打表 #include<cstdio> #include<cstring> #include<iostream> #includ ...

  6. 【luogu P2491 [SDOI2011]消防】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2491 题外话: OI一共只有三种题--会的题,不会的题,二分题. 题解: step 1 求树的直径,把树的直 ...

  7. 【luogu P1040 加分二叉树】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1040 今天考试考了一个区间DP...没错就是这个... 太蒟了真是连区间DP都不会...看了看题解也看不懂, ...

  8. Luogu P1351 联合权值 题解

    这是一个不错的树形结构的题,由于本蒟蒻不会推什么神奇的公式其实是懒得推...,所以很愉快的发现其实只需要两个点之间的关系为祖父和儿子.或者是兄弟即可. 然后问题就变得很简单了,只需要做一个正常的DFS ...

  9. 【luogu P1850 换教室】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1850 难的不在状态上,难在转移方程. (话说方程写错居然还有84分= =) #include <cst ...

随机推荐

  1. 【bzoj3669】魔法森林

    Portal-->bzoj3669 Solution ​  愉悦智力康复ing ​​  这题的话有两个比较关键的地方 ​​  首先是答案肯定是原图的某个生成树上的一条路径,那么我们考虑怎么来找这 ...

  2. 图像处理之Canny边缘检测

    http://blog.csdn.net/jia20003/article/details/41173767 图像处理之Canny 边缘检测 一:历史 Canny边缘检测算法是1986年有John F ...

  3. java Ftp上传创建多层文件的代码片段

    StringBuilder sBuilder = new StringBuilder();            String[] pah = path.split("/");   ...

  4. bzoj3938 Robot

    3938: Robot Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 336  Solved: 112[Submit][Status][Discuss ...

  5. php整理

    linux上安装php配套环境有些繁琐 推荐使用一键安装: https://lnmp.org/install.html phalcon框架环境: centos7下php7.0.x安装phalcon框架

  6. Idea安装findbugs插件,以及findbugs安装find security bugs插件

    第一:先讲述Idea怎么安装findbugs插件 具体操作如下面的图所示: 然后就可以安装findbugs 第二:findbugs怎么安装find security bugs这个find bugs的插 ...

  7. js 生成二维码

    $(".good_info").on('click',function () { var id = $(this).data('id'); var string = 'http:/ ...

  8. webservice 采用SSL实现加密传输

    本文转自:http://book.51cto.com/art/200906/129770.htm http://yeweiyun868.blog.163.com/blog/static/5637844 ...

  9. flex属性设置详解

    CSS代码中常见这样的写法:flex:1 这是flex 的缩写: flex-grow.flex-shrink.flex-basis,其取值可以考虑以下情况: 1. flex 的默认值是以上三个属性值的 ...

  10. Window启动Zookeeper报错java.lang.NumberFormatException: For input string:

    用zkServer start命令报如题的错误,改为直接用zkServer启动则ok 还有在window下,myid文件不能是myid.txt,不能带文件格式 dataDir=D:/zookeeper ...