天鹅会面题解
Posted Forever_goodboy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了天鹅会面题解相关的知识,希望对你有一定的参考价值。
题目描述
两头白天鹅生活在一个部分湖面结了冰的湖泊中,湖面的形状为一个长方形,并且被分割成R行C列的小方格,某些方格中结了冰,这样的方格称之为冰格,其余的方格称之为水格。冬天过去了,湖面上的冰渐渐开始溶解了,每一天与水相邻的冰格就将消融而转化为水格。所谓两个方格相邻是指它们在水平或垂直方向有公共边,两个呈对角的方格是不相邻的,下图给出样例数据的演化过程。
白天鹅只能在水中沿水平或垂直方向游动,写一个程序判断多少天后两只白天鹅才能够相会。
【输入格式】
输入文件第一行包含两个用空格隔开的整数R和C,其中1 ≤ R, C ≤ 1500,接下来的R行每行包含C个字符,描述湖面的初始状态,‘·’表示水格,‘ X’表示冰格,‘ L’表示一只白天鹅。
【输出格式】
输出文件仅一行包含一个整数表示两只白天鹅等到相邻那一天所需的天数。
【输入样例】
8 17
...XXXXXX..XX.XXX
....XXXXXXXXX.XXX
...XXXXXXXXXXXX..
..XXXXX.LXXXXXX..
.XXXXXX..XXXXXX..
XXXXXXX...XXXX...
..XXXXX...XXX....
....XXXXX.XXXL...
【输出样例】
2
Hint
30%数据1 ≤ R《400.1 ≤ C《300
100%其中1 ≤ R, C ≤ 1500
solution:
这题没别的一看肯定是搜索,先一遍bfs处理出来每一个点最少需要几点化成水(本来是水的为0天),然后在一遍bfs跑到达这点的最优路径中的最大天数,这里需要注意的是一个点会在好几条路径上,所以有可能进队出对好几次不能用vis数组判断被访问或就不在访问,这样得到的路径只是其中最先访问的一条,但不一定是上最优的,再跑一遍bfs就可以啦。
考试的时候脑残把第二个bfs换成了dfs结果呵呵了。。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define N 1505 7 int r,c,blo; 8 char read() { 9 char ch=getchar(); 10 while(ch!=‘X‘&&ch!=‘.‘&&ch!=‘L‘) { 11 ch=getchar(); 12 } 13 return ch; 14 } 15 char s[N][N]; 16 int ji1x,ji1y,ji2x,ji2y,head,tail; 17 int step[N][N]; 18 struct node { 19 int x,y; 20 } queue[20000005]; 21 void bfs() { 22 while(head<tail) { 23 int x=queue[++head].x,y=queue[head].y; 24 if(step[x+1][y]>step[x][y]+1&&x<r) { 25 step[x+1][y]=step[x][y]+1; 26 queue[++tail].x=x+1; 27 queue[tail].y=y; 28 } 29 if(step[x-1][y]>step[x][y]+1&&x>1) { 30 step[x-1][y]=step[x][y]+1; 31 queue[++tail].x=x-1; 32 queue[tail].y=y; 33 } 34 if(step[x][y+1]>step[x][y]+1&&y<c) { 35 step[x][y+1]=step[x][y]+1; 36 queue[++tail].x=x; 37 queue[tail].y=y+1; 38 } 39 if(step[x][y-1]>step[x][y]+1&&y>1) { 40 step[x][y-1]=step[x][y]+1; 41 queue[++tail].x=x; 42 queue[tail].y=y-1; 43 } 44 } 45 } 46 bool in[N][N]; 47 int ans=0x7fffffff; 48 int ji[N][N]; 49 void bfs2() { 50 memset(queue,0,sizeof(queue)); 51 memset(ji,0x5f,sizeof(ji)); 52 head=tail=0; 53 queue[++tail].x=ji1x; 54 queue[tail].y=ji1y; 55 in[ji1x][ji1y]=1; 56 ji[ji1x][ji1y]=0; 57 while(head<tail) { 58 int x=queue[++head].x,y=queue[head].y; 59 in[x][y]=0; 60 if(x==ji2x&&y==ji2y) { 61 ans=min(ans,ji[x][y]); 62 continue; 63 } 64 if(max(step[x+1][y],ji[x][y])<ji[x+1][y]&&x<r) { 65 ji[x+1][y]=max(step[x+1][y],ji[x][y]); 66 if(!in[x+1][y]) { 67 in[x+1][y]=1; 68 queue[++tail].x=x+1; 69 queue[tail].y=y; 70 } 71 } 72 if(max(step[x-1][y],ji[x][y])<ji[x-1][y]&&x>1) { 73 ji[x-1][y]=max(step[x-1][y],ji[x][y]); 74 if(!in[x-1][y]) { 75 in[x-1][y]=1; 76 queue[++tail].x=x-1; 77 queue[tail].y=y; 78 } 79 } 80 if(max(step[x][y+1],ji[x][y])<ji[x][y+1]&&y<c) { 81 ji[x][y+1]=max(step[x][y+1],ji[x][y]); 82 if(!in[x][y+1]) { 83 in[x][y+1]=1; 84 queue[++tail].x=x; 85 queue[tail].y=y+1; 86 } 87 } 88 if(max(step[x][y-1],ji[x][y])<ji[x][y-1]&&y>1) { 89 ji[x][y-1]=max(step[x][y-1],ji[x][y]); 90 if(!in[x][y-1]) { 91 in[x][y-1]=1; 92 queue[++tail].x=x; 93 queue[tail].y=y-1; 94 } 95 } 96 } 97 } 98 int main() { 99 freopen("swan.in","r",stdin); 100 freopen("sdsd.out","w",stdout); 101 memset(step,0x5f,sizeof(step)); 102 scanf("%d%d",&r,&c); 103 head=tail=0; 104 for(int i=1; i<=r; i++) { 105 for(int j=1; j<=c; j++) { 106 s[i][j]=read(); 107 if(s[i][j]==‘L‘) { 108 if(!ji1x) { 109 ji1x=i; 110 ji1y=j; 111 } else { 112 ji2x=i; 113 ji2y=j; 114 } 115 } 116 if(s[i][j]==‘L‘||s[i][j]==‘.‘) { 117 queue[++tail].x=i; 118 queue[tail].y=j; 119 step[i][j]=0; 120 } 121 } 122 } 123 bfs(); 124 bfs2(); 125 cout<<ans; 126 return 0; 127 }
以上是关于天鹅会面题解的主要内容,如果未能解决你的问题,请参考以下文章
C语言必会面试题(3耶稣有13个门徒,当中有一个就是出卖耶稣的叛徒,请用排除法找出这位叛徒:13人围坐一圈,从第一个開始报号:1,2,3,1,2,3...。凡是报到“3”就退出圈子,...)(代码片段