Poj 1027
类似于消灭星星的游戏,每次选择棋盘中最大的连通块删除,删除后上方棋子按顺序下落,若有一列为空,右边棋子整列左移。连通块最左边最下面的棋子为连通块位置,若两个连通块大小相同,选择左边的,同一列选择下面的。
模拟题,更新棋盘的时候用两个指针,一个快指针一个慢指针,一次循环搞定
广度搜索的时候一定要边界检查啊 偷懒没有边界检查结果WA了几次
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 5 struct Cluster{ 6 char C;//颜色 7 int r;//行 8 int c;//列 9 int b;//球的数量 10 }; 11 12 char game[10][15];//记录棋盘 13 Cluster clu[150];//记录连通块 14 int maxx;//最大连通块的下标 15 int num;//连通块的个数 16 int sum;//总分数 17 int rest;//剩余棋子个数 18 int k;//第k次游戏 19 bool vis[10][15];//广度搜索时用来标记的数组 20 21 void bfs(int i,int j){//广度搜索 22 vis[i][j]=1; 23 clu[num].b++;//当前连通块棋子个数+1 24 if(!vis[i+1][j]&&game[i][j]==game[i+1][j]&&i+1<10){ 25 bfs(i+1,j); 26 } 27 if(!vis[i-1][j]&&game[i][j]==game[i-1][j]&&i-1>=0){ 28 bfs(i-1,j); 29 } 30 if(!vis[i][j+1]&&game[i][j]==game[i][j+1]&&j+1<15){ 31 bfs(i,j+1); 32 } 33 if(!vis[i][j-1]&&game[i][j]==game[i][j-1]&&j-1>=0){ 34 bfs(i,j-1); 35 } 36 } 37 38 void findcluster(){//记录所有连通块并且记录最大连通块 39 memset(vis,0,sizeof(vis)); 40 memset(clu,0,sizeof(clu)); 41 maxx=0; 42 num=0; 43 for(int j=0;j<15;j++){ 44 for(int i=0;i<10;i++){ 45 if(!vis[i][j]&&game[i][j]!='X'){ 46 clu[num].r=i; 47 clu[num].c=j; 48 clu[num].b=0; 49 clu[num].C=game[i][j]; 50 bfs(i,j); 51 if(clu[num].b>clu[maxx].b){ 52 maxx=num; 53 } 54 num++; 55 } 56 } 57 } 58 } 59 60 void change(int i,int j){//将需要删除的棋子变为'X' 61 game[i][j]='X'; 62 if(clu[maxx].C==game[i+1][j]&&i+1<10){ 63 change(i+1,j); 64 } 65 if(clu[maxx].C==game[i-1][j]&&i-1>=0){ 66 change(i-1,j); 67 } 68 if(clu[maxx].C==game[i][j+1]&&j+1<15){ 69 change(i,j+1); 70 } 71 if(clu[maxx].C==game[i][j-1]&&j-1>=0){ 72 change(i,j-1); 73 } 74 } 75 76 void remove(){//删除棋子更新棋盘 77 change(clu[maxx].r,clu[maxx].c); 78 int begin; 79 for(int j=0;j<15;j++){ 80 begin=0; 81 for(int i=0;i<10;i++){ 82 if(game[begin][j]!='X'&&game[i][j]=='X'){ 83 begin=i; 84 } 85 else if(game[begin][j]=='X'&&game[i][j]!='X'){ 86 game[begin][j]=game[i][j]; 87 game[i][j]='X'; 88 begin++; 89 } 90 } 91 }//棋子下移 92 begin=0; 93 for(int j=0;j<15;j++){ 94 if(game[0][begin]!='X'&&game[0][j]=='X'){ 95 begin=j; 96 } 97 else if(game[0][begin]=='X'&&game[0][j]!='X'){ 98 for(int i=0;i<10;i++){ 99 game[i][begin]=game[i][j]; 100 game[i][j]='X'; 101 } 102 begin++; 103 } 104 }//棋子左移 105 } 106 107 int main(){ 108 int n; 109 int move;//记录步骤 110 cin>>n; 111 k=1; 112 while(n--){ 113 for(int i=9;i>=0;i--){ 114 for(int j=0;j<15;j++){ 115 cin>>game[i][j]; 116 } 117 } 118 move=1; 119 sum=0; 120 rest=150; 121 cout<<"Game "<<k<<": "<<endl<<endl; 122 while(game[0][0]!='X'){ 123 findcluster(); 124 if(clu[maxx].b==1){ 125 break; 126 } 127 remove(); 128 cout<<"Move "<<move<<" at ("<<clu[maxx].r+1<<","<<clu[maxx].c+1<<"): "<< 129 "removed "<<clu[maxx].b<<" balls of color "<<clu[maxx].C<<", got "<<(clu[maxx].b-2)*(clu[maxx].b-2)<<" points. "<<endl; 130 sum+=(clu[maxx].b-2)*(clu[maxx].b-2); 131 rest-=clu[maxx].b; 132 move++; 133 134 } 135 if(rest==0){ 136 sum+=1000; 137 } 138 cout<<"Final score: "<<sum<<", with "<<rest<<" balls remaining. "<<endl<<endl; 139 k++; 140 } 141 }