当前位置: 代码迷 >> 综合 >> ZOJ3780 Paint the Grid Again(模拟)
  详细解决方案

ZOJ3780 Paint the Grid Again(模拟)

热度:47   发布时间:2023-12-06 19:52:50.0

题目传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3780

题意:

给一块n*n的格子,每次可以将任意行变成X,或任意列变成O,后操作的将覆盖原先的操作。给出最终图形,要求操作的步骤最少,并按先后顺序输出操作方法(字典序)。

分析:

其实这道题虽然要求操作的步骤最少,但是经过分析可以得知操作的总步骤肯定是一定的。只要按照逆字典序向前模拟删除行和列,最后只要都能删完就说明有解。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 505;
char mp[maxn][maxn];
int n;
bool judge()
{for(int i = 0; i < n; i++)for(int j = 0; j < n; j++)if(mp[i][j] != '.')return true;return false;
}
int ans[maxn*2];
char a[maxn*2];
bool row[maxn], col[maxn];
int main()
{int T, flag, need;scanf("%d", &T);while(T--){scanf("%d", &n);for(int i = 0; i < n; i++)scanf("%s", mp[i]);int cnt = 0;memset(row, false, sizeof(row));memset(col, false, sizeof(col));while(true){need = flag = 0;for(int i = n-1; i >= 0; i--){need = 0;if(row[i+1])continue;int j;for(j = 0; j < n; j++){if(mp[i][j] == 'X')need = 1;if(mp[i][j] == 'O')break;}if(j == n && need){flag = 1;for(j = 0; j < n; j++)mp[i][j] = '.';ans[cnt] = i+1;a[cnt++] = 'R';row[i+1] = true;break;}}need = 0;for(int j = n-1; j >= 0 && flag == 0; j--){need = 0;int i;if(col[j+1])continue;for(i = 0; i < n; i++){if(mp[i][j] == 'O')need = 1;if(mp[i][j] == 'X')break;}if(i == n && need){flag = 1;for(i = 0; i < n; i++)mp[i][j] = '.';ans[cnt] = j+1;a[cnt++] = 'C';col[j+1] = true;break;}}if(flag == 1)continue;if(flag == 0 && !judge()){flag = 1;break;}else{break;}}if(flag)k{for(int i = cnt-1; i >= 0; i--)printf("%c%d%c", a[i], ans[i], i == 0 ? '\n':' ');}elseprintf("No solution\n");}return 0;
}


  相关解决方案