[kuangbin带你飞]专题一 简单搜索(回顾)
注意条件:不能每放一个棋子,就标记一行和一列,我们直接枚举每一行就可以了。
AC代码:
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 using namespace std; 5 # define ll long long 6 const int maxn =2100; 7 char str[maxn][maxn]; 8 int vis[maxn]; 9 int n,m,num; 10 void dfs(int u,int cnt) 11 { 12 if(cnt==m) 13 { 14 num++; 15 return ; 16 } 17 if(u==n) 18 return ; 19 for(int i=0; i<n; i++) 20 { 21 if(!vis[i]&&str[u][i]=='#') 22 { 23 vis[i]=1; 24 dfs(u+1,cnt+1); 25 vis[i]=0; 26 } 27 } 28 dfs(u+1,cnt); 29 } 30 int main() 31 { 32 while(~scanf("%d %d",&n,&m)) 33 { 34 if(n==-1&&m==-1) 35 break; 36 memset(vis,0,sizeof(vis)); 37 num=0; 38 for(int i=0; i<n; i++) 39 { 40 scanf("%s",str[i]); 41 } 42 dfs(0,0); 43 printf("%d\n",num); 44 } 45 return 0; 46 }
B - Dungeon Master
注意条件:简单三维bfs。
AC代码:
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<queue> 5 using namespace std; 6 # define ll long long 7 const int maxn =50; 8 char str[maxn][maxn][maxn]; 9 int vis[maxn][maxn][maxn]; 10 int f[3][6]= {{1,-1,0,0,0,0}, 11 {0,0,-1,1,0,0}, 12 {0,0,0,0,1,-1} 13 }; 14 int n,m,k; 15 int stx,sty,stz; 16 int edx,edy,edz; 17 int ans; 18 bool judge(int x,int y,int z) 19 { 20 if(x>=1&&x<=n&&y>=1&&y<=m&&z>=1&&z<=k) 21 return true; 22 return false; 23 } 24 struct node 25 { 26 int x,y,z,step; 27 node() {} 28 node(int xx,int yy,int zz,int tt) 29 { 30 x=xx,y=yy,z=zz,step=tt; 31 } 32 }; 33 void bfs(int x,int y,int z) 34 { 35 queue<node>q; 36 q.push(node(x,y,z,0)); 37 vis[x][y][z]=1; 38 while(!q.empty()) 39 { 40 node top=q.front(); 41 q.pop(); 42 if(top.x==edx&&top.y==edy&&top.z==edz) 43 { 44 ans=top.step; 45 return ; 46 } 47 for(int i=0; i<6; i++) 48 { 49 int tx,ty,tz; 50 tx=top.x+f[0][i]; 51 ty=top.y+f[1][i]; 52 tz=top.z+f[2][i]; 53 if(judge(tx,ty,tz)&&vis[tx][ty][tz]==0&&str[tx][ty][tz]!='#') 54 { 55 vis[tx][ty][tz]=1; 56 q.push(node(tx,ty,tz,top.step+1)); 57 } 58 } 59 } 60 } 61 int main() 62 { 63 while(~scanf("%d %d %d",&n,&m,&k)&&(n+m+k)) 64 { 65 memset(vis,0,sizeof(vis)); 66 ans=-1; 67 for(int i=1; i<=n; i++) 68 { 69 for(int j=1; j<=m; j++) 70 { 71 scanf("%s",str[i][j]+1); 72 for(int l=1; l<=k; l++) 73 { 74 if(str[i][j][l]=='S') 75 { 76 stx=i; 77 sty=j; 78 stz=l; 79 } 80 if(str[i][j][l]=='E') 81 { 82 edx=i; 83 edy=j; 84 edz=l; 85 } 86 } 87 } 88 } 89 bfs(stx,sty,stz); 90 if(ans==-1) 91 printf("Trapped!\n"); 92 else 93 printf("Escaped in %d minute(s).\n",ans); 94 } 95 return 0; 96 }
C - Catch That Cow
注意条件:bfs,注意限制条件。
AC代码:
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<queue> 5 using namespace std; 6 # define ll long long 7 const int maxn =2e5+100; 8 int vis[maxn]; 9 pair<int,int> top; 10 int bfs(int st,int ed){ 11 queue<pair<int,int> >q; 12 vis[st]=1; 13 q.push(make_pair(st,0)); 14 while(!q.empty()){ 15 top=q.front(); 16 q.pop(); 17 if(top.first==ed){ 18 return top.second; 19 } 20 if(top.first+1<=ed&&vis[top.first+1]==0){ 21 vis[top.first+1]=1; 22 q.push(make_pair(top.first+1,top.second+1)); 23 } 24 if(top.first-1>=0&&vis[top.first-1]==0){ 25 vis[top.first-1]=1; 26 q.push(make_pair(top.first-1,top.second+1)); 27 } 28 if(top.first*2<=2*ed&&vis[top.first*2]==0){ 29 vis[top.first*2]=1; 30 q.push(make_pair(top.first*2,top.second+1)); 31 } 32 } 33 } 34 int main(){ 35 int n,m; 36 while(~scanf("%d %d",&n,&m)){ 37 memset(vis,0,sizeof(vis)); 38 int ans=bfs(n,m); 39 printf("%d\n",ans); 40 } 41 return 0; 42 }
D - Fliptile
注意条件:直接枚举第一行,然后通过下面的一行调整为他的上一行全为0.找出最小步骤,如果存在多个最小步骤相等。找出字典序最小的(对第一行二进制枚举就可以保证了)
AC代码:
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 using namespace std; 5 # define ll long long 6 # define inf 0x3f3f3f3f 7 const int maxn = 20; 8 int a[maxn][maxn]; 9 int tmp[maxn][maxn]; 10 int ans[maxn][maxn]; 11 int com[maxn][maxn]; 12 int n,m,ti; 13 void flip(int x,int y){ 14 ti++; 15 tmp[x][y]^=1; 16 tmp[x+1][y]^=1; 17 tmp[x-1][y]^=1; 18 tmp[x][y+1]^=1; 19 tmp[x][y-1]^=1; 20 } 21 bool judge(int t){ 22 memcpy(tmp,a,sizeof(a)); 23 memset(com,0,sizeof(com)); 24 for(int i=m;i>=1;i--){ 25 com[1][m-i+1]=((t&(1<<(i-1)))>0?1:0); 26 } 27 for(int i=1;i<=m;i++){ 28 if(com[1][i])flip(1,i); 29 } 30 for(int i=2;i<=n;i++){ 31 for(int j=1;j<=m;j++){ 32 if(tmp[i-1][j])flip(i,j),com[i][j]=1; 33 } 34 } 35 for(int i=1;i<=n;i++){ 36 for(int j=1;j<=m;j++){ 37 if(tmp[i][j])return false; 38 } 39 } 40 return true; 41 } 42 int main(){ 43 scanf("%d %d",&n,&m); 44 for(int i=1;i<=n;i++){ 45 for(int j=1;j<=m;j++){ 46 scanf("%d",&a[i][j]); 47 } 48 } 49 int maxstate=(1<<m)-1; 50 int maxx=inf; 51 for(int i=0;i<=maxstate;i++){ 52 ti=0; 53 if(judge(i)){ 54 if(maxx>ti){ 55 maxx=ti; 56 memcpy(ans,com,sizeof(com)); 57 } 58 } 59 } 60 if(maxx==inf){ 61 printf("IMPOSSIBLE\n"); 62 } 63 else { 64 for(int i=1;i<=n;i++){ 65 for(int j=1;j<=m;j++){ 66 if(j==1)printf("%d",ans[i][j]); 67 else printf(" %d",ans[i][j]); 68 } 69 printf("\n"); 70 } 71 } 72 return 0; 73 } 74 //溜了,回家玩耍的