【Luogu】P3930 SAC E#1 - 一道大水题 Knight
【题目】洛谷10月月赛R1 提高组
【题意】给定n*n棋盘和<=16个棋子,给几个棋子种类和攻击范围,现我方只有一马,求能否吃王。
【算法】状压+BFS
【题解】16种棋子中,马不能吃马,直接处理马和王,那么就剩13个棋子,可以压成2^13表示棋盘现有棋子存活状态。
然后对vis[2^13][n][n]进行bfs。
细节:
1.攻击直到碰到其它棋子,那个碰到的棋子也算攻击范围内。
2.判断碰到棋子时,注意该棋子是否在当前局面存活。
3.多组数据,Q中途退出要清空。
学到了:
1.一份长代码要细心经营,视若珍宝,动键盘之前要冷静把思路和框架理清楚,过程中步步为营,慢慢写总能写完的。
2.不要轻易相信自己的代码没有bug了,尽量对拍,把小数据的中间结果输出和手算比较正确性,从而改掉尽可能多的错误。
3.不要害怕写长的复杂的代码,先做框架,然后一步一步把子过程做好,一份超长代码就慢慢构造出来了。
4.枚举对角线的姿势!
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f,maxn=;
int n,mp[<<][maxn][maxn],map[maxn][maxn],p[maxn][maxn],ans;
int cnt,tot,Tx,Ty,Sx,Sy;
bool vis[<<][maxn][maxn];
struct Node{int x,y;}c[],ch[];
struct cyc{int S,x,y,st;};
queue<cyc>Q;
void qishi(int S,int x,int y){
mp[S][x-][y+]=mp[S][x+][y+]=mp[S][x+][y-]=mp[S][x+][y+]=;
if(x->)mp[S][x-][y-]=mp[S][x-][y+]=;
if(y->)mp[S][x-][y-]=mp[S][x+][y-]=;
}
void king(int S,int x,int y){
mp[S][x-][y-]=mp[S][x-][y]=mp[S][x-][y+]=;
mp[S][x][y-]=mp[S][x][y+]=;
mp[S][x+][y-]=mp[S][x+][y]=mp[S][x+][y+]=;
}
bool m(int S,int x,int y){
if(map[x][y]<=)return ;
if(map[x][y]==||map[x][y]==)return ;
if(S&(<<(p[x][y]-)))return ;
return ;
}
void chengbao(int S,int x,int y){
for(int i=x-;i>=;i--)if(m(S,i,y))mp[S][i][y]=;else{mp[S][i][y]=;break;}
for(int i=x+;i<=n;i++)if(m(S,i,y))mp[S][i][y]=;else{mp[S][i][y]=;break;}
for(int i=y-;i>=;i--)if(m(S,x,i))mp[S][x][i]=;else{mp[S][x][i]=;break;}
for(int i=y+;i<=n;i++)if(m(S,x,i))mp[S][x][i]=;else{mp[S][x][i]=;break;}
}
void zhujiao(int S,int x,int y){
for(int i=;i<min(x,y);i++)if(m(S,x-i,y-i))mp[S][x-i][y-i]=;else{mp[S][x-i][y-i]=;break;}
for(int i=;i<=min(n-x,n-y);i++)if(m(S,x+i,y+i))mp[S][x+i][y+i]=;else{mp[S][x+i][y+i]=;break;}
for(int i=;i<=min(x,n-y);i++)if(m(S,x-i,y+i))mp[S][x-i][y+i]=;else{mp[S][x-i][y+i]=;break;}
for(int i=;i<=min(n-x,y);i++)if(m(S,x+i,y-i))mp[S][x+i][y-i]=;else{mp[S][x+i][y-i]=;break;}
}
void soldier(int S,int x,int y){
mp[S][x+][y-]=mp[S][x+][y+]=;
}
void check(int S,int x,int y,int st){
if(x<||x>n||y<||y>n||mp[S][x][y]||vis[S][x][y])return;
vis[S][x][y]=;
if(map[x][y]==)ans=st;
if(map[x][y]>=&&map[x][y]<=)if(S&(<<(p[x][y]-)))S^=(<<(p[x][y]-));
vis[S][x][y]=;
Q.push((cyc){S,x,y,st});
}
char s[maxn];
int main(){
while(scanf("%d",&n)==){
cnt=tot=;
memset(map,,sizeof(map));memset(p,,sizeof(p));memset(mp,,sizeof(mp));memset(vis,,sizeof(vis));
for(int i=;i<=n;i++){
scanf("%s",s+);
for(int j=;j<=n;j++){
if(s[j]=='K')map[i][j]=,c[++cnt].x=i,c[cnt].y=j;
if(s[j]=='X')map[i][j]=,Tx=i,Ty=j,c[++cnt].x=i,c[cnt].y=j;
if(s[j]=='O')Sx=i,Sy=j;
if(s[j]=='C')map[i][j]=,ch[tot].x=i,ch[tot].y=j,p[i][j]=tot++;
if(s[j]=='B')map[i][j]=,ch[tot].x=i,ch[tot].y=j,p[i][j]=tot++;
if(s[j]=='Q')map[i][j]=,ch[tot].x=i,ch[tot].y=j,p[i][j]=tot++;
if(s[j]=='P')map[i][j]=,ch[tot].x=i,ch[tot].y=j,p[i][j]=tot++;
}
}
for(int S=;S<(<<tot);S++){
for(int i=;i<=cnt;i++)if(map[c[i].x][c[i].y]==)qishi(S,c[i].x,c[i].y);else king(S,c[i].x,c[i].y);
for(int i=;i<tot;i++)if((<<i)&S){
int x=ch[i].x,y=ch[i].y;
if(map[x][y]==)chengbao(S,x,y);
if(map[x][y]==)zhujiao(S,x,y);
if(map[x][y]==)chengbao(S,x,y),zhujiao(S,x,y);
if(map[x][y]==)soldier(S,x,y);
}
mp[S][Tx][Ty]=;
}
if(mp[(<<tot)-][Sx][Sy]==){printf("-1\n");continue;}
while(!Q.empty())Q.pop();
Q.push((cyc){(<<tot)-,Sx,Sy,});vis[(<<tot)-][Sx][Sy]=;
ans=;
while(!Q.empty()){
cyc q=Q.front();Q.pop();
check(q.S,q.x-,q.y-,q.st+);check(q.S,q.x-,q.y+,q.st+);
check(q.S,q.x-,q.y-,q.st+);check(q.S,q.x-,q.y+,q.st+);
check(q.S,q.x+,q.y-,q.st+);check(q.S,q.x+,q.y+,q.st+);
check(q.S,q.x+,q.y-,q.st+);check(q.S,q.x+,q.y+,q.st+);
if(ans)break;
}
if(ans==)printf("-1\n");else printf("%d\n",ans);
}
return ;
}
【Luogu】P3930 SAC E#1 - 一道大水题 Knight的更多相关文章
- P3930 SAC E#1 - 一道大水题 Knight
TLE,额 ,有空再写吧. #include<queue> #include<cstdio> #include<vector> #include<algori ...
- [洛谷3930]SAC E#1 - 一道大水题 Knight
Description 他们经常在一起玩一个游戏,不,不是星际争霸,是国际象棋.毒奶色觉得F91是一只鸡.他在一个n×n的棋盘上用黑色的城堡(车).骑士(马).主教(象).皇后(副).国王(帅).士兵 ...
- 第三届山西省赛1004 一道大水题(scanf)
一道大水题 时间限制: C/C++ 2000ms; Java 4000ms 内存限制: 65535KB 通过次数: 44 总提交次数: 1020 问题描述 Dr. Pan作为上兰帝国ACM的总负责人, ...
- 【数据结构】 最小生成树(四)——利用kruskal算法搞定例题×3+变形+一道大水题
在这一专辑(最小生成树)中的上一期讲到了prim算法,但是prim算法比较难懂,为了避免看不懂,就先用kruskal算法写题吧,下面将会将三道例题,加一道变形,以及一道大水题,水到不用高级数据结构,建 ...
- 【Luogu】P3927 SAC E#1 - 一道中档题 Factorial
[题目]洛谷10月月赛R1 提高组 [题意]求n!在k进制下末尾0的个数,n<=1e18,k<=1e16. [题解]考虑10进制末尾0要考虑2和5,推广到k进制则将k分解质因数. 每个质因 ...
- 【Luogu】 P3928 SAC E#1 - 一道简单题 Sequence2
[题目]洛谷10月月赛R1 提高组 [算法]递推DP+树状数组 [题解]列出DP递推方程,然后用树状数组维护前后缀和. #include<cstdio> #include<cstri ...
- 【洛谷十月月测】 P3927 SAC E#1 - 一道中档题 Factorial
题目传送门:https://www.luogu.org/problemnew/show/P3927 题目大意:给你两个正整数n,k,求n!在k进制下末尾零的数量. 我们通过简单的数学分析,便可以发现, ...
- 2013年山东省第四届ACM大学生程序设计竞赛-最后一道大水题:Contest Print Server
点击打开链接 2226: Contest Print Server Time Limit: 1 Sec Memory Limit: 128 MB Submit: 53 Solved: 18 [Su ...
- SAC E#1 - 一道神题 Sequence1
题目背景 小强和阿米巴是好朋友. 题目描述 小强很喜欢数列.有一天,他心血来潮,写下了一个数列. 阿米巴也很喜欢数列.但是他只喜欢其中一种:波动数列. 一个长度为n的波动数列满足对于任何i(1 < ...
随机推荐
- [core python programming]chapter 7 programming MS office
excel.pyw会有问题,解决如下: 因为python3x中没有tkMessageBox模块,Tkinter改成了tkinter你可以查看你的py当前支持的模块.在交互式命令行下输入>> ...
- Spring学习(二)—— java的动态代理机制
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
- vue服务端渲染axios预取数据
首先是要参考vue服务端渲染教程:https://ssr.vuejs.org/zh/data.html. 本文主要代码均参考教程得来.基本原理如下,拷贝的原文教程. 为了解决这个问题,获取的数据需要位 ...
- 性能分析Linux服务器CPU利用率(转)
1. 指标范围 1.1 User mode CPU utilization+ System mode CPU utilization 合理值:60-85%,如果在一个多用户系统中us+sy时间超过 ...
- 解决编写 xml 没有代码提示
有时候在编写 struts.xml 会没有代码提示,一般是因为没有联网导致的,或者之前配置过 dtd 文件 url,但是文件路径之后被修改了. 解决方案有: 让电脑联网 修改 dtd 的本地路径以及 ...
- 如何取得dbgrid中未保存(post)的值(50分)
比如说处在编辑状态时,想取得当前记录值 Dataset.fields[0].Value 就是当前值:Dataset.fields[0].OldValue 就是原始值. 呵呵,我指得是在编辑时,就是按键 ...
- HDFS文件操作命令手册
HDFS文件操作的基本格式是: bin/hadoop dfs -cmd <args> 1. cat $ hadoop dfs -cat URI [URI …] #将参数所指示的文件的内容输 ...
- 【数论数学】【P2152】【SDOI2009】Super GCD
传送门 Description Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比赛计算GCD.有一天Sheng bill很嚣张地找到了 ...
- LoadRunner中的IP欺骗
应用程序服务器和网络设备使用IP地址来识别客户端.应用程序服务器通常会对来自同一计算机的客户端信息进行高速缓存. 网络路由器尝试对原信息和目标信息进行高速缓存以优化吞吐量.如果多个用户具有相同的IP地 ...
- 删除空格-sed
如下,我需要提取出‘wan’这个字符串.可以发现在‘wan’的前后是有空格,需要将其删除. # lxc list # lxc list | grep lxdbr0 | awk -F "|&q ...