标签:
题目描述 Description
有一个5×5的棋盘,上面有一些格子被染成了黑色,其他的格子都是白色,你的任务的对棋盘一些格子进行染色,使得所有的黑色格子能连成一块,并且你染色的格子数目要最少。读入一个初始棋盘的状态,输出最少需要对多少个格子进行染色,才能使得所有的黑色格子都连成一块。(注:连接是指上下左右四个方向,如果两个黑色格子只共有一个点,那么不算连接)
输入包括一个5×5的01矩阵,中间无空格,1表示格子已经被染成黑色。
输出最少需要对多少个格子进行染色
11100
11000
10000
01111
11111
1
well…搜索…先bfs找到黑的再扩展进行染色。判断么…用dfs判断是否连通。怀着高兴的心情提交上去。。。果然TLE了。。
呃呃好吧。我改一下判重。
原来是一个一个对比的,现在我把它转化成25位的二进制数,可以省去不少时间。
AC。。
#include <iostream> #include <cstring> using namespace std; typedef char zt[5][5]; zt m,q[500001],v; int f,r,num[500001],dx[4]={-1,1,0,0},dy[4]={0,0,-1,1}; bool vis[33554435]; int black[25][2],count=-1; int s; void dfs(zt ttpp,int xx,int yy) { if(xx<0||xx>=5||yy<0||yy>=5||v[xx][yy]||ttpp[xx][yy]==‘0‘) return; v[xx][yy]=1; for (int dd=0;dd<4;dd++) dfs(ttpp,xx+dx[dd],yy+dy[dd]); } int okay(zt tp) { int i; memset(v,0,sizeof(v)); for (i=0;i<25;i++) if (tp[i/5][i%5]==‘1‘) break; dfs(tp,i/5,i%5); for (int i=0;i<5;i++) for (int j=0;j<5;j++) if (tp[i][j]==‘1‘ && !v[i][j]) return 0; return 1; } int change_to_int(zt tt) { int rrr=0,d=1; for (int i=4;i>=0;i--) for (int j=4;j>=0;j--) { rrr+=(tt[i][j]-‘0‘)*d; d*=2; } return rrr; } int bfs() { f=0;r=1; for (int i=0;i<5;i++) for (int j=0;j<5;j++) q[1][i][j]=m[i][j]; num[1]=0; s=change_to_int(m); vis[s]=1; while (f<r) { f++; if (okay(q[f])) return num[f]; count=-1; for (int i=0;i<5;i++) for (int j=0;j<5;j++) if (q[f][i][j]==‘1‘) { black[++count][0]=i; black[count][1]=j; } for (int i=0;i<=count;i++) for (int j=0;j<4;j++) { int nx=black[i][0]+dx[j]; int ny=black[i][1]+dy[j]; if (nx<0||nx>=5||ny<0||ny>=5||q[f][nx][ny]==‘1‘) continue; r++; for (int i=0;i<5;i++) for (int j=0;j<5;j++) { q[r][i][j]=q[f][i][j]; } q[r][nx][ny]=‘1‘; s=change_to_int(q[r]); if (!vis[s]) { vis[s]=1; num[r]=num[f]+1; } else r--; } } return 0; } int main() { for (int i=0;i<5;i++) for (int j=0;j<5;j++) cin >> m[i][j]; cout << bfs() << "\n"; }
标签:
原文地址:http://www.cnblogs.com/zcyhhh/p/5687658.html