【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 < ...
随机推荐
- iOS开发自定义试图切换
CATransition *transition = [CATransition animation]; transition.duration = 1.0f; transition.timingFu ...
- C#,Winform 文件的导入导出 File
1.导入 导入对话框:OpenFileDialog private void sbtnsb_Click(object sender, EventArgs e) { try { OpenFileDial ...
- 第二部分shell编程2正则(grepegrepsedawk)
一.grep/egrep 1. 语法+选项语法: grep [-cinvABC] 'word' filename -c :打印符合要求的行数-n :在输出符合要求的行的同时连同行号一起输出 -v :打 ...
- [剑指Offer] 48.不用加减乘除做加法
题目描述 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. [思路] 首先看十进制是如何做的: 5+7=12,三步走第一步:相加各位的值,不算进位,得到2.第二步:计算进 ...
- android四大组件(一)Activity
一.创建一个新的Activity 1.android的四大组件都要在清单文件里面配置 2.如果想让你的应用有多个启动图标,你的activity需要这样配置 <intent-filter> ...
- Log-spectral distance
Log-spectral distance对数频谱距离 log-spectral distance(LSD),也指 log-spectral distortion,是两个频谱之间的距离度量(用分贝表示 ...
- HDU - 6333 Harvest of Apples
题意: T次询问,每次给出n,m.求sigma(k:0->m)C(n, k). 题解: 用离线莫队来做. 令S(n,m) = sigma(k:0->m)C(n, k). S(n+1, m) ...
- AOJ.176 两数组最短距离 (乱搞题)
两数组最短距离 点我挑战题目 题意分析 给出2个数组,让求出2个数组元素差的绝对值的最小值是多少. 我这里是o(m+n)的算法.首先对于第一个数组,让他的第一个元素和第二个元素比较,如果他的第一个元素 ...
- 【线段树】【P3372】模板-线段树
百度百科 Definition&Solution 线段树是一种log级别的树形结构,可以处理区间修改以及区间查询问题.期望情况下,复杂度为O(nlogn). 核心思想见百度百科,线段树即将每个 ...
- GSM之AT操作命令详解20160615
因工作接触到GSM模块,所以收集整理了一下关于操作GSM模块的AT命令的资料: 1.AT的历史与应用 1.1 AT的历史AT命令集是由拨号调制解调器(MODEM)的发明者贺氏公司(Hayes)为了控制 ...