【题目】洛谷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的更多相关文章

  1. P3930 SAC E#1 - 一道大水题 Knight

    TLE,额 ,有空再写吧. #include<queue> #include<cstdio> #include<vector> #include<algori ...

  2. [洛谷3930]SAC E#1 - 一道大水题 Knight

    Description 他们经常在一起玩一个游戏,不,不是星际争霸,是国际象棋.毒奶色觉得F91是一只鸡.他在一个n×n的棋盘上用黑色的城堡(车).骑士(马).主教(象).皇后(副).国王(帅).士兵 ...

  3. 第三届山西省赛1004 一道大水题(scanf)

    一道大水题 时间限制: C/C++ 2000ms; Java 4000ms 内存限制: 65535KB 通过次数: 44 总提交次数: 1020 问题描述 Dr. Pan作为上兰帝国ACM的总负责人, ...

  4. 【数据结构】 最小生成树(四)——利用kruskal算法搞定例题×3+变形+一道大水题

    在这一专辑(最小生成树)中的上一期讲到了prim算法,但是prim算法比较难懂,为了避免看不懂,就先用kruskal算法写题吧,下面将会将三道例题,加一道变形,以及一道大水题,水到不用高级数据结构,建 ...

  5. 【Luogu】P3927 SAC E#1 - 一道中档题 Factorial

    [题目]洛谷10月月赛R1 提高组 [题意]求n!在k进制下末尾0的个数,n<=1e18,k<=1e16. [题解]考虑10进制末尾0要考虑2和5,推广到k进制则将k分解质因数. 每个质因 ...

  6. 【Luogu】 P3928 SAC E#1 - 一道简单题 Sequence2

    [题目]洛谷10月月赛R1 提高组 [算法]递推DP+树状数组 [题解]列出DP递推方程,然后用树状数组维护前后缀和. #include<cstdio> #include<cstri ...

  7. 【洛谷十月月测】 P3927 SAC E#1 - 一道中档题 Factorial

    题目传送门:https://www.luogu.org/problemnew/show/P3927 题目大意:给你两个正整数n,k,求n!在k进制下末尾零的数量. 我们通过简单的数学分析,便可以发现, ...

  8. 2013年山东省第四届ACM大学生程序设计竞赛-最后一道大水题:Contest Print Server

    点击打开链接 2226: Contest Print Server Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 53  Solved: 18 [Su ...

  9. SAC E#1 - 一道神题 Sequence1

    题目背景 小强和阿米巴是好朋友. 题目描述 小强很喜欢数列.有一天,他心血来潮,写下了一个数列. 阿米巴也很喜欢数列.但是他只喜欢其中一种:波动数列. 一个长度为n的波动数列满足对于任何i(1 < ...

随机推荐

  1. aria2 on ubuntu

    http://www.5yun.org/9102.html http://jpollo.logdown.com/posts/160847-aria2c-and-yaaw aria2c --enable ...

  2. Where to go from here

    Did you get through all of that content? Congratulations! You've learnt the fundamentals of algorith ...

  3. OSG学习:移动/缩放/旋转模型

    移动和缩放以及旋转都是对矩阵进行操作,这些操作如果要叠加直接矩阵相乘就可以了. 下面的示例代码中,加入了四个bignathan,一个是默认加入在最中间,一个向上移2单位,一个是向下移2单位且缩放0.5 ...

  4. asp.net中Repeater结合js实现checkbox的全选/全不选

    前台界面代码: <input name="CheckAll" type="checkbox" id="CheckAll" value= ...

  5. 【Linux】- Ubuntu 配置mysql远程访问

    ubuntu上安装mysql非常简单只需要几条命令就可以完成. sudo apt-get install mysql-server   安装过程中会提示设置密码什么的,注意设置了不要忘了,安装完成之后 ...

  6. 【Linux】- mv命令

    Linux mv命令用来为文件或目录改名.或将文件或目录移入其它位置. 语法 mv [options] source dest mv [options] source... directory 参数说 ...

  7. 从一个ListBox中的元素点击导入另一个ListBox元素中

    先看效果图:

  8. (沒有介紹標準算法的)RMQ問題

    感謝杜哥代碼滋磁 //以下是廢話 RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中 ...

  9. Elasticsearch 中文分词器IK

    1.安装说明 https://github.com/medcl/elasticsearch-analysis-ik 2.release版本 https://github.com/medcl/elast ...

  10. 【题解】CF#855 G-Harry Vs Voldemort

    个人感觉挺有意思的,然而被颜神D无聊惹(- ̄▽ ̄)- 这题我们可以首先试图去统计以每一个点作为 w 点所能对答案造成的贡献是多少.不难发现,当且仅当 u 和 v 都在 w 所在边双的一侧的时候不能构成 ...