Paint the Grid Again
题目链接: ZOJ - 3780题意:一个N*N的格子, 一开始是空白的, 每次可以将一列变为O或将一行变为X;给出最终的状态, 问最少需要多少个操作才能将白纸变为给出的状态, 若可以按字典序输出, 操作, 反之输出“No solution”;
在有O的一列中有X, 那么一定是在这一列先刷了O, 再在对应行刷X;
在有X的一行中有O, 那么一定是在这一行先刷了X, 再在对应列刷O;
现在将行的点与列的点看作不同的点, 可以看作是一种拓扑关系;
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
int n;
char maze[510][510];
int cnt[1100], fr[510], fc[510];
vector<int> vec[1100];
void init(){
memset(fc, 0, sizeof(fc));
memset(fr, 0, sizeof(fr));
memset(cnt, 0, sizeof(cnt));
for(int i=0; i<n+510; i++) vec[i].clear();
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
if(maze[i][j]=='O') fc[j]=1;
else fr[i]=1;
}
}
for(int i=0; i<n; i++){
if(!fr[i]) continue;
for(int j=0; j<n; j++){
if(maze[i][j]=='O'){
vec[i].push_back(j+510);
cnt[j+510]++;
}
}
}
for(int j=0; j<n; j++){
if(!fc[j]) continue;
for(int i=0; i<n; i++){
if(maze[i][j]=='X'){
vec[j+510].push_back(i);
cnt[i]++;
}
}
}
return;
}
void topsort(){
priority_queue<int, vector<int>, greater<int> > q;
for(int i=0; i<n+510; i++){
if(cnt[i]==0&&vec[i].size()!=0){
q.push(i);
}
}
int flag=0;
while(!q.empty()){
int tmp=q.top();
q.pop();
for(int i=0; i<vec[tmp].size(); i++){
int t=vec[tmp][i];
cnt[t]--;
if(!cnt[t]){
q.push(t);
}
}
if(tmp<510) printf("%sR%d", flag?" ":"", tmp+1), flag=1;
else printf("%sC%d", flag?" ":"", tmp-510+1), flag=1;
}
if(flag) printf("\n");
else printf("No solution\n");
return;
}
int main(){
int T;
cin >> T;
while(T--){
scanf("%d", &n);
for(int i=0; i<n; i++)
scanf("%s", maze[i]);
init();
topsort();
}
return 0;
}