博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ZOJ 3780 Paint the Grid Again(隐式图拓扑排序)
阅读量:4323 次
发布时间:2019-06-06

本文共 3938 字,大约阅读时间需要 13 分钟。

Paint the Grid Again

Time Limit: 2 Seconds      
Memory Limit: 65536 KB

Leo has a grid with N × N cells. He wants to paint each cell with a specific color (either black or white).

Leo has a magical brush which can paint any row with black color, or any column with white color. Each time he uses the brush, the previous color of cells will be covered by the new color. Since the magic of the brush is limited, each row and each column can only be painted at most once. The cells were painted in some other color (neither black nor white) initially.

Please write a program to find out the way to paint the grid.

Input

There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:

The first line contains an integer N (1 <= N <= 500). Then N lines follow. Each line contains a string with N characters. Each character is either 'X' (black) or 'O' (white) indicates the color of the cells should be painted to, after Leo finished his painting.

Output

For each test case, output "No solution" if it is impossible to find a way to paint the grid.

Otherwise, output the solution with minimum number of painting operations. Each operation is either "R#" (paint in a row) or "C#" (paint in a column), "#" is the index (1-based) of the row/column. Use exactly one space to separate each operation.

Among all possible solutions, you should choose the lexicographically smallest one. A solution X is lexicographically smaller than Y if there exists an integer k, the first k - 1 operations of X and Y are the same. The k-th operation of X is smaller than the k-th in Y. The operation in a column is always smaller than the operation in a row. If two operations have the same type, the one with smaller index of row/column is the lexicographically smaller one.

Sample Input

22XXOX2XOOX

Sample Output

R2 C1 R1No solution

题目链接:

比赛的时候真心没想出来,这题居然是用拓扑排序做,不得不膜拜一下。

做法:题目中最重要的条件就是每一行或每一列最多只能变换一次,考虑一个格子$(i,j)$,若它是'X'则说明它肯定是先刷$j$列后刷$i$行变换得到的;若为'O'则是先刷$i$行后刷$j$列的变换得到,那么$n*n$个格子可以得到$n*n$种顺序条件,最后再看能否存在一种拓扑序列同时符合这么多的条件,若符合则说明按照这个拓扑序列去刷可以刷出给定的字符样式。那么问题就成了拓扑排序问题了。最后题目要求字典序最小的方案,由于列变换字符'C'的字典序比行变换'R'的字典序小,因此把列号设为$1$~$n$,行号设为$n+1$~$2n$,而且要求变换的行列坐标也要最小,因此用最小堆的优先队列来代替普通队列进行拓扑排序,一开始的入度为0的点实际上是不用刷的,因为一开始的点是没有行、列顺序要求的。比如单一个点'X',拓扑序为第1列->第1行,但是显然刷第1列这个操作是多余的。

代码:

#include 
#include
using namespace std;#define INF 0x3f3f3f3f#define LC(x) (x<<1)#define RC(x) ((x<<1)+1)#define MID(x,y) ((x+y)>>1)#define CLR(arr,val) memset(arr,val,sizeof(arr))#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);typedef pair
pii;typedef long long LL;const double PI = acos(-1.0);const int N = 510;struct edge{ int to, nxt; edge() {} edge(int _to, int _nxt): to(_to), nxt(_nxt) {}} E[N * N];char s[N][N];int head[N << 1], tot;int deg[N << 1], no_use[N << 1];vector
ans;void init(){ CLR(head, -1); tot = 0; CLR(deg, 0); CLR(no_use, 0); ans.clear();}inline void add(int s, int t){ E[tot] = edge(t, head[s]); head[s] = tot++;}int Top_sort(int n){ int i, u; priority_queue
, greater
>Q; for (i = 1; i <= n; ++i) { if (!deg[i]) { Q.push(i); no_use[i] = 1; } } while (!Q.empty()) { u = Q.top(); Q.pop(); ans.push_back(u); for (i = head[u]; ~i; i = E[i].nxt) { int v = E[i].to; if (!--deg[v]) Q.push(v); } } return (int)ans.size() == n;}int main(void){ int tcase, n, i, j; scanf("%d", &tcase); while (tcase--) { init(); scanf("%d", &n); for (i = 1; i <= n; ++i) scanf("%s", s[i] + 1); for (i = 1; i <= n; ++i) //N*N { for (j = 1; j <= n; ++j) { if (s[i][j] == 'X') add(j, i + n), ++deg[i + n]; else add(i + n, j), ++deg[j]; } } if (!Top_sort(n << 1)) puts("No solution"); else { int sz = ans.size(); for (i = 0; i < sz; ++i) { int x = ans[i]; if (no_use[x]) continue; printf("%c%d%s", x <= n ? 'C' : 'R', x <= n ? x : x - n, i == sz - 1 ? "\n" : " "); } } } return 0;}

转载于:https://www.cnblogs.com/Blackops/p/6659883.html

你可能感兴趣的文章
工具:linux 性能监控工具-nmon
查看>>
fatal error C1853
查看>>
Response.Expires 属性 (转载于疯狂客的BLOG)
查看>>
Ural 1001 - Reverse Root
查看>>
玩转webpack之webpack的entry output
查看>>
java 操作mongodb查询条件的常用设置
查看>>
黑马程序员_java基础笔记(02)...java语言基础组成
查看>>
关于缓存击穿
查看>>
对innodb 拷贝文件实现数据库的方式(转)
查看>>
python知识点 2014-07-09
查看>>
FloatingActionButton的一点学习感悟
查看>>
ABAP CDS ON HANA-(10)項目結合して一つ項目として表示
查看>>
网站地址信息
查看>>
产品经理 - 登录 注册
查看>>
小白的python进阶历程------05.占位符
查看>>
CF414BMashmokh and ACMDP
查看>>
Notepad++ 通过g++编译
查看>>
Manacher算法,最长回文串
查看>>
git rm–r folder fatal:pathspec "" did not match any files
查看>>
词法分析
查看>>