洛谷 P5512 [NOIP1997 提高组] 棋盘问题 加强版
洛谷 P5512 [NOIP1997 提高组] 棋盘问题 加强版
Problem&Background
Solution
首先先完成这道题的普通版本P1549
A了那一道题之后,您尝试着测一测比较大的数据,结果发现完全没有输出awa
为了AC这道题,您当然可以打表,那么就不必继续看些去了;当然,您也可以继续优化下去——
于是就有了这一篇题解。
在上一篇题解中,我给出了五个剪枝,可以获得70pts。接下来继续想一些更加细致的剪枝。
剪枝6
打表也是一种剪枝——减去比较大的数据——不是吗?
写出70pts的代码之后就可以让计算机挂机计算\(n>7\)这三种情况。
可以同时计算。我的电脑不超过10min就计算出了\(n=8\).
以此类推。
Code
/**************************************************************
* Problem: 5512
* Author: Vanilla_chan
* Date: 20210315
**************************************************************/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<limits.h>
#define IL inline
#define re register
#define LL long long
#define ULL unsigned long long
#ifdef TH
#define debug printf("Now is %d\n",__LINE__);
#else
#define debug
#endif
#ifdef ONLINE_JUDGE
char buf[1<<23],* p1=buf,* p2=buf,obuf[1<<23],* O=obuf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
using namespace std;
template<class T>inline void read(T& x)
{
char ch=getchar();
int fu;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') fu=-1,ch=getchar();
x=ch-'0';ch=getchar();
while(isdigit(ch)) { x=x*10+ch-'0';ch=getchar(); }
x*=fu;
}
inline int read()
{
int x=0,fu=1;
char ch=getchar();
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') fu=-1,ch=getchar();
x=ch-'0';ch=getchar();
while(isdigit(ch)) { x=x*10+ch-'0';ch=getchar(); }
return x*fu;
}
int G[55];
template<class T>inline void write(T x)
{
int g=0;
if(x<0) x=-x,putchar('-');
do { G[++g]=x%10;x/=10; } while(x);
for(int i=g;i>=1;--i)putchar('0'+G[i]);putchar('\n');
}
#define M 210
#define N 20
int n;
bool book[M];
int prime[M][M];
void init()
{
book[1]=1;
for(int i=2;i<=200;i++)
{
if(!book[i])
{
for(int j=2;i*j<=200;j++)
{
book[i*j]=1;
}
}
}
for(int i=1;i<=n*n;i++)
for(int j=1;j<=n*n;j++)
prime[i][j]=book[i+j];
}
int ans;
int ANS[N][N];
int now[N][N];
bool vis[M];
int dt[4][2]={0,1,0,-1,1,0,-1,0};
IL bool exist(int x)
{
return x>=1&&x<=n;
}
bool check(int x,int y)
{
for(int t=0;t<4;t++)
{
if(exist(x+dt[t][0])&&exist(y+dt[t][1]))
{
if(now[x+dt[t][0]][y+dt[t][1]]!=0)
{
if(prime[now[x][y]][now[x+dt[t][0]][y+dt[t][1]]])
{
return 0;
}
}
}
}
return 1;
}
void dfs3(int x,int y,int sum)
{
if(sum>=ans) return;
if(y==n+1) y=2,x++;
if(x==n+1)
{
ans=sum;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
ANS[i][j]=now[i][j];
}
}
return;
}
for(int i=n*n;i>=1;i--)
{
if(vis[i]) continue;
vis[i]=1;
now[x][y]=i;
if(check(x,y)) dfs3(x,y+1,sum);
vis[i]=0;
now[x][y]=0;
}
}
void dfs2(int y,int sum)
{
if(sum>=ans) return;
if(y==n+1)
{
dfs3(2,2,sum);
return;
}
for(int i=1;i<=n*n;i++)
{
if(vis[i]) continue;
vis[i]=1;
now[1][y]=i;
if(check(1,y)) dfs2(y+1,sum+i);
now[1][y]=0;
vis[i]=0;
}
}
void dfs1(int x,int sum)
{
if(sum>=ans) return;
if(x==n+1)
{
dfs2(2,sum);
return;
}
for(int i=1;i<=n*n;i++)
{
if(vis[i]) continue;
vis[i]=1;
now[x][1]=i;
if(check(x,1)) dfs1(x+1,sum+i);
vis[i]=0;
now[x][1]=0;
}
}
int main()
{
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
n=read();
if(n>=8)
{
if(n==8)
{
cout<<"1 2 3 4 7 6 5 14"<<endl;
cout<<"12 17 20 27 34 25 18 23"<<endl;
cout<<"11 26 21 32 39 28 61 36"<<endl;
cout<<"8 15 46 51 58 31 48 35"<<endl;
cout<<"9 22 57 52 55 42 41 62"<<endl;
cout<<"10 19 40 49 54 47 56 45"<<endl;
cout<<"13 24 43 60 53 50 33 64"<<endl;
cout<<"16 37 30 29 44 59 38 63"<<endl;
}
if(n==9)
{
cout<<"1 2 3 4 7 6 5 8 9"<<endl;
cout<<"10 21 20 27 34 25 18 23 38"<<endl;
cout<<"13 40 33 26 45 28 19 24 35"<<endl;
cout<<"16 31 76 81 68 69 70 79 72"<<endl;
cout<<"15 22 51 56 71 80 57 52 37"<<endl;
cout<<"14 39 62 41 60 47 32 75 64"<<endl;
cout<<"17 44 65 48 49 54 77 74 63"<<endl;
cout<<"12 29 42 55 58 73 36 53 50"<<endl;
cout<<"11 30 67 46 43 66 61 78 59"<<endl;
}
if(n==10)
{
cout<<"1 2 3 4 7 6 5 8 9 10"<<endl;
cout<<"12 29 38 33 34 25 36 23 44 27"<<endl;
cout<<"11 30 59 68 45 28 43 24 35 26"<<endl;
cout<<"18 41 42 71 56 75 64 37 66 47"<<endl;
cout<<"13 48 19 60 53 98 93 100 91 90"<<endl;
cout<<"16 31 40 97 54 83 74 99 82 67"<<endl;
cout<<"15 22 49 52 55 96 77 80 57 46"<<endl;
cout<<"14 39 58 79 72 95 62 87 70 61"<<endl;
cout<<"17 50 51 88 85 78 89 92 81 76"<<endl;
cout<<"20 21 32 69 94 73 84 65 86 63"<<endl;
}
return 0;
}
init();
now[1][1]=1;
vis[1]=1;
ans=100000;
dfs1(2,0);
if(ans==100000) cout<<"NO"<<endl;
else
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cout<<ANS[i][j]<<" ";
}
cout<<endl;
}
}
return 0;
}
洛谷 P5512 [NOIP1997 提高组] 棋盘问题 加强版的更多相关文章
- 洛谷P6033 [NOIP2004 提高组] 合并果子 加强版 (单调队列)
数据加强了,原来nlogn的复杂度就不行了...... 首先对原来的n个数排序(注意不能用快排),因为值域是1e5,所以可以开桶排序,开两个队列,一个存原来的n个数(已经满足单增),另一队列存两两合并 ...
- 洛谷P1312 [NOIP2011提高组Day1T3]Mayan游戏
Mayan游戏 题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游 ...
- 洛谷 P2678 & [NOIP2015提高组] 跳石头
题目链接 https://www.luogu.org/problemnew/show/P2678 题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布 ...
- 洛谷 P1025 & [NOIP2001提高组] 数的划分(搜索剪枝)
题目链接 https://www.luogu.org/problemnew/show/P1025 解题思路 一道简单的dfs题,但是需要剪枝,否则会TLE. 我们用dfs(a,u,num)来表示上一个 ...
- 洛谷P1514 [NOIP2010提高组T4]引水入城
P1514 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城 ...
- 洛谷P1084 [NOIP2012提高组Day2T3]疫情控制
P1084 疫情控制 题目描述 H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树,1 号城市是首都,也是树中的根节点. H 国的首都爆发了一种危害性极高的传染病.当局为了控 ...
- 洛谷P1083 [NOIP2012提高组Day2T2]借教室
P1083 借教室 题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借 ...
- 洛谷P1315 [NOIP2011提高组Day2T3] 观光公交
P1315 观光公交 题目描述 风景迷人的小城Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第 0 分钟出现在 1号 ...
- 洛谷P1313 [NOIP2011提高组Day2T1]计算系数
P1313 计算系数 题目描述 给定一个多项式(by+ax)^k,请求出多项式展开后x^n*y^m 项的系数. 输入输出格式 输入格式: 输入文件名为factor.in. 共一行,包含5 个整数,分别 ...
- 洛谷P1003 [NOIP2011提高组Day1T1]铺地毯
P1003 铺地毯 题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号 ...
随机推荐
- Selenium Javascript 滚动条操作
js在selenium有许多应用,最主要的有滚动条操作. 实现功能:进入百度搜索结果页->滚动条分别滚到到顶部.底部及指定元素位置. 使用格式: driver.execute_script('w ...
- Kubernetes:根据进程 Pid 获取 Pod 名称
前言 在管理 Kubernetes 集群的过程中,我们经常会遇到这样一种情况:在某台节点上发现某个进程资源占用量很高,却又不知道是哪个容器里的进程.有没有办法可以根据进程 PID 快速找到 Pod 名 ...
- ubuntu apt 安装报错:Media change: please insert the disc labeled 'Ubuntu 20.04.5 LTS Focal Fossa - Release amd64 (20220831)' in the drive '/cdrom/' and press [Enter]
前言 如果你在 Ubuntu 上使用 apt 安装软件包时遇到 "Media change: please insert the disc labeled ..." 的错误消息,这 ...
- Netty基础—8.Netty实现私有协议栈
大纲 1.私有协议介绍 2.私有协议的通信模型 3.私有协议栈的消息定义 4.私有协议栈链路的建立 5.私有协议栈链路的关闭 6.私有协议栈的心跳机制 7.私有协议栈的重连机制 8.私有协议栈的重复登 ...
- Windows下PostgreSQL设置远程连接以及备份和恢复数据库
一.设置远程连接 修改安装路径下的postgresql.conf,定位到listen_address = '*',确保其值为'*'(Windows下默认是这样的,可不用修改) 修改安装路径下的pg_ ...
- 开源!Django-Vue3-Admin的Python后台管理系统
Django-Vue3-Admin 项目简介 Django-Vue3-Admin 是一个基于 Django + Vue3 的前后端分离的后台管理系统,采用了最新的前后端技术栈,内置了丰富的功能模块,可 ...
- Zabbix Scheduled reports中文乱码
困扰了一天的问题,最后还是靠百度大神的方法解决.原文链接 https://blog.csdn.net/weixin_38587368/article/details/119357516 由于我的是容器 ...
- 调用 restful的api的方法
var // myurl : string; tmpstr : String;// string; RespData :TStringStream; sendData : TStringList; j ...
- C 冒泡排序和选择排序
冒泡排序 理论概念: 从第一个数开始,将相邻的两个数比较,第一个数和第二个数比较,比如说是从小到大的排序,要是后面的数比前面的小则交换两个的位置,这样第一轮比较基数后最大的数就到了最后面,接着进行第二 ...
- soapUI参数化总结
1.新建项目目录 以获取用户贡献等级为例,目录如下: 2.添加DataSource和DataSource Loop 选中Test Step右键分别新建DataSource和DataSource Loo ...