将每个不是障碍的格子标号,设三只狼的位置分别为$A,B,C$,羊的位置在$D$。合法状态中强行限制$A<B<C$,这样状态数只有$\frac{n^8}{6}\approx 1.6\times 10^7$。

设$f[S],g[S]$表示目前局面是$S$,狼/羊正在决策,最优情况下羊会不会被围住。

  • 若$f[S]$的某个后继$g[T]$是真,那么$f[S]$也是真。
  • 若$g[S]$的所有后继$f[T]$都是真,那么$g[S]$也是真。

先认为所有$f[S]$和$g[S]$都是假,并记录每个$g[S]$的后继个数$deg[S]$。

对于羊被围住的状态,将它们的$g$设为真,加入队列。

每次从队列中取出一个状态:

  • 若是$g[S]$,则枚举$g[S]$的所有前驱$f[T]$,将它们更新为真,并加入队列。
  • 若是$f[S]$,则枚举$f[S]$的所有前驱$g[T]$,将$deg[T]$减一,若$deg[T]$变为了$0$则将$g[T]$更新为真,并加入队列。

时间复杂度$O(n^8)$。

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=10,M=161701;
int n,m,all,tot,i,j,k,x,y,z,A,B,S;bool can[N*N],safe[N*N];char a[N][N+5];
int id[N*N][N*N][N*N],loc[M][3];
int tr[N*N][4];
bool f[M][N*N],g[M][N*N];
char deg[M][N*N];
int q[M*N*N*2],head,tail;
inline int getid(int x,int y){return x*m+y;}
inline void extf(int A,int B,int C,int y){
if(A>B)swap(A,B);
if(B>C)swap(B,C);
if(A>B)swap(A,B);
int x=id[A][B][C];
if(f[x][y])return;
f[x][y]=1;
q[++tail]=(x<<8)|(y<<1);
}
inline void extg(int x,int y){
g[x][y]=1;
q[++tail]=(x<<8)|(y<<1)|1;
}
int main(){
while(~scanf("%d%d",&n,&m)){
for(i=0;i<n;i++)scanf("%s",a[i]);
all=n*m;
for(i=0;i<all;i++)can[i]=safe[i]=0;
for(i=0;i<n;i++)for(j=0;j<m;j++){
if(a[i][j]!='X')can[getid(i,j)]=1;
if(i==0||i==n-1||j==0||j==m-1)safe[getid(i,j)]=1;
}
for(i=0;i<n;i++)for(j=0;j<m;j++)for(k=0;k<4;k++){
tr[getid(i,j)][k]=-1;
int nx=i,ny=j;
if(k==0)nx--;
if(k==1)nx++;
if(k==2)ny--;
if(k==3)ny++;
if(nx<0||nx>=n||ny<0||ny>=m)continue;
if(a[i][j]!='X'&&a[nx][ny]!='X')tr[getid(i,j)][k]=getid(nx,ny);
}
tot=0;
for(i=0;i<all;i++)if(can[i])for(j=i+1;j<all;j++)if(can[j])for(k=j+1;k<all;k++)if(can[k]){
id[i][j][k]=tot;
loc[tot][0]=i;
loc[tot][1]=j;
loc[tot][2]=k;
tot++;
}
for(i=0;i<tot;i++)for(j=0;j<all;j++)f[i][j]=g[i][j]=deg[i][j]=0;
head=1,tail=0;
for(i=0;i<tot;i++){
x=loc[i][0],y=loc[i][1],z=loc[i][2];
for(j=0;j<all;j++)if(can[j]){
if(j==x||j==y||j==z)continue;
if(safe[j]){deg[i][j]++;continue;}
for(k=0;k<4;k++){
int o=tr[j][k];
if(o<0)continue;
if(o==x||o==y||o==z)continue;
deg[i][j]++;
}
if(!deg[i][j])extg(i,j);
}
}
while(head<=tail){
S=q[head++];
A=S>>8,B=S>>1&127;
x=loc[A][0],y=loc[A][1],z=loc[A][2];
if(S&1){
bool flag=0;
for(k=0;k<4;k++){
int o=tr[x][k];
if(o<0)continue;
if(o==y||o==z||o==B)continue;
flag=1;
extf(o,y,z,B);
}
for(k=0;k<4;k++){
int o=tr[y][k];
if(o<0)continue;
if(o==x||o==z||o==B)continue;
flag=1;
extf(x,o,z,B);
}
for(k=0;k<4;k++){
int o=tr[z][k];
if(o<0)continue;
if(o==x||o==y||o==B)continue;
flag=1;
extf(x,y,o,B);
}
if(!flag)extf(x,y,z,B);
}else{
for(k=0;k<4;k++){
int o=tr[B][k];
if(o<0)continue;
if(safe[o])continue;
if(o==x||o==y||o==z)continue;
if(!(--deg[A][o]))extg(A,o);
}
}
}
x=y=z=-1;
for(i=0;i<n;i++)for(j=0;j<m;j++){
if(a[i][j]=='S')B=getid(i,j);
if(a[i][j]=='W'){
if(x<0)x=getid(i,j);
else if(y<0)y=getid(i,j);
else z=getid(i,j);
}
}
if(x>y)swap(x,y);
if(y>z)swap(y,z);
if(x>y)swap(x,y);
puts(f[id[x][y][z]][B]?"danger":"safe");
}
return 0;
}

  

BZOJ1991 : Pku2422 The Wolves and the Sheep的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. [CF] 948A Protect Sheep

    A. Protect Sheep time limit per test1 second memory limit per test256 megabytes inputstandard input ...

  3. Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1)A. Protect Sheep

    http://codeforces.com/contest/948/problem/A   A. Protect Sheep Bob is a farmer. He has a large pastu ...

  4. Codeforces Round #470 (Div. 2) A Protect Sheep (基础)输入输出的警示、边界处理

    Bob is a farmer. He has a large pasture with many sheep. Recently, he has lost some of them due to w ...

  5. 2001. Counting Sheep

      After a long night of coding, Charles Pearson Peterson is having trouble sleeping. This is not onl ...

  6. hdu 3046 Pleasant sheep and big big wolf 最小割

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3046 In ZJNU, there is a well-known prairie. And it a ...

  7. 【DFS深搜初步】HDOJ-2952 Counting Sheep、NYOJ-27 水池数目

    [题目链接:HDOJ-2952] Counting Sheep Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 ...

  8. Counting sheep...

    Counting sheep... Description: Consider an array of sheep where some sheep may be missing from their ...

  9. HDU-2952 Counting Sheep (DFS)

    Counting Sheep Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Tota ...

随机推荐

  1. 【ShaderToy】抗锯齿相关函数

    *示例代码可以直接在ShaderToy中运行. *我放在这里咯ShaderToy基础学习中~欢迎交流(ノ>ω<)ノ 先上未抗锯齿的两个圆形图案,可以清楚看清图案边缘像素块,即“锯齿”. 附 ...

  2. 使用JQuery实现图片轮播效果

    [效果如图] [原理简述] 这里大概说一下整个流程: 1,将除了第一张以外的图片全部隐藏, 2,获取第一张图片的alt信息显示在信息栏,并添加点击事件 3,为4个按钮添加点击侦听,点击相应的按钮,用f ...

  3. 原生JS实现banner图的滚动与跳转

    HTML部分: <div id="banner"> <!--4张滚动的图片--> <div id="inside"> < ...

  4. CSS3 Background-clip

    上一节在<CSS3 background-size>详细的介绍了CSS3为background新增属性之一,今天和大家一起来学习CSS3中有关于Background的第二新属性Backgr ...

  5. 错误: ‘shared_ptr’ in namespace ‘std’ does not name a type的解决方法。

    这是因为要使用C++11的标准编译,而catkin_make时无法识别出来. 修改方法是在CMakeLists.txt文件里面添加: set(CMAKE_CXX_FLAGS "${CMAKE ...

  6. 医学图像数据(一)——TCIA基本介绍

    1.介绍 The Cancer Imaging Archive (TCIA)是癌症研究的医学图像的开放获取数据库.该网站由国家癌症研究所(NCI)癌症影像计划资助,合同由阿肯色大学医学科学院管理.存档 ...

  7. 备考2019年6月份PMP考试-分享一些(备考)考试心得

    I'm iron man,纪念离去的钢铁侠(复联4) 话说任何一个写程序的人都不可能干一辈子(有些人例外),大部分都是要转行的. 技术转管理是一条路,技术转创业是一条路,技术干销售是一条路,技术转售前 ...

  8. Filebeat 启动关闭流程

    启动阶段: instance/beat.go #打印home路径.配置路径.数据路径和日志路径 seccomp #Syscall filter检查 instance/beat.go #beat inf ...

  9. 【easy】784. Letter Case Permutation

    Examples: Input: S = "a1b2" Output: ["a1b2", "a1B2", "A1b2", ...

  10. windows2012服务器中安装php7+mysql5.7+apache2.4环境

    1.下载安装apache.2.4 https://home.apache.org/~steffenal/VC14/binaries/httpd-2.4.38-win64-VC14.zip 解压到d盘的 ...