题意很好懂,大致就是三种颜色,红和蓝一起会变绿,给个终态矩阵,问从原始状态到终态最少画几笔? 按一定规则画
思路就是记红为1,蓝为2,绿为3,先遍历绿色,针对每一块绿色进行删除,每找到一块绿色,首先将它置零,然后主对角线上和它挨着的红色或绿色-1,副对角线上和它挨着的蓝色或绿色-2,ans+2; 知道所有绿色遍历完为止。然后在遍历剩余的红色和蓝色,红色块主对角线上和它挨着的红色-1(包括它)ans+1,绿色副对角线上和它挨着的蓝色-2(包括它)ans+1。 最后输出ans即可。
#include<cstdio> #include<cstring> #include<iostream> using namespace std; int n,m; int g[51][51]; int ans=0; void dfs_1(int x,int y) //左上 { while(g[x][y]==1||g[x][y]==3) { // puts("1"); g[x][y]--; x--; y--; } } void dfs_2(int x,int y) // 右下 { while(g[x][y]==1||g[x][y]==3) { // puts("1"); g[x][y]--; x++; y++; } } void dfs_3(int x,int y) // 左下 { while(g[x][y]==2||g[x][y]==3) { // puts("1"); g[x][y]-=2; x++; y--; } } void dfs_4(int x,int y) // 右上 { while(g[x][y]==2||g[x][y]==3) { // puts("1"); g[x][y]-=2; x--; y++; } } int main() { int t; scanf("%d",&t); while(t--) { ans=0; memset(g,0,sizeof(g)); scanf("%d",&n); for(int i=1;i<=n;i++) { char cc[51]; memset(cc,‘\0‘,sizeof(cc)); scanf("%s",cc); m=strlen(cc); for(int j=0;j<m;j++) { if(cc[j]==‘R‘) g[i][j+1]=1; if(cc[j]==‘B‘) g[i][j+1]=2; if(cc[j]==‘G‘) g[i][j+1]=3; } } for(int a=1;a<=n;a++) { for(int b=1;b<=m;b++) { if(g[a][b]==3) { g[a][b]=0; dfs_1(a-1,b-1); dfs_2(a+1,b+1); dfs_3(a+1,b-1); dfs_4(a-1,b+1); ans+=2; } } } for(int c=1;c<=n;c++) { for(int d=1;d<=m;d++) { if(g[c][d]==1) { g[c][d]=0; dfs_1(c-1,d-1); dfs_2(c+1,d+1); ans++; } else if(g[c][d]==2) { g[c][d]=2; dfs_3(c+1,d-1); dfs_4(c-1,d+1); ans++; } } } printf("%d\n",ans); } }
时间: 2024-11-06 21:22:34