【ZOJ - 3780】Paint the Grid Again(拓扑排序,图论,证明性质)
題干:
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?Tindicating 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
2 2 XX OX 2 XO OXSample Output
R2 C1 R1 No solution題目大意:
對一個空白的矩陣進行兩種操作:可以將一行涂黑,將一列涂白,每一行每一列只能涂一次,給最終的圖案,要求用最少次數涂出要求的圖案并輸出步驟。如果有多種可能性滿足,那就輸出字典序最小解。定義字典序:前k-1個操作相同的話,比較第k個。列比行的優先級高,其次是行(列)號小的優先級高。
解題報告:
? 首先需要證明的是行列之間的約束是唯一的。也就是不存在先某一行再某一列? 或者? 先某一列再某一行? 同時成立的情況。猜出結論,然后嘗試證明。對于每一個格子拆成n行,n列,這是一個二分圖,對于每一個格子,相當于是一個約束,如果這個格子的最終值是X,說明列比行優先,反之說明行比列優先。假設A比B優先,那么我們就A->B連一條邊。所以我們有n^2個約束關系。也就是說對于那個二分圖,任意行列之間都有一個連線,那么他是個完全二分圖,所以如果存在先行后列和先列后行都可以的情況,那么對于選中的那一行和那一列的那個交點來說,就是先行在列或者先列在行都可以。這就產生了矛盾,因為這顯然是不符合我們剛剛構造的那個二分圖的,因為剛開始是個空白圖,也就是說如果這個格子所在的行列都在答案內,那么順序是根據這個點的值是X還是O早就被確定了的,所以不可能有先行再列或者先列行都存在的情況這是不可能的。
所以我們拓撲排序的時候只需要維護那個下標之間的大小關系就可以了,對于行列之間的關系我們完全不需要管,因為完全不會存在這里的矛盾。這就大大簡化了問題。
再其次就是那個vis數組的含義了,這一點也不難理解,因為我們要求的是字典序最小,所以沒必要的操作我們肯定是希望做的越少越好,所以用vis來判斷對這一行(列)的約束有幾條了,如果約束很多,比如對某一行的約束到達了n條,說明我畫不畫這一行其實都差不了多少,因為最后這一行都要被覆蓋成列的顏色(也就是都是O)那么我還要涂這一行干啥呢?
所以有這一個操作來減少沒必要的操作,符合題意。有的時候題目給了很多限制但是其實都用不到,因為題目雖然沒有說輸出任意解,但是有的時候約束還是很少的,有的時候他只是這樣迷惑你而已。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define F first #define S second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int MAX = 2e5 + 5; char s[MAX]; int vis[MAX],in[MAX],n; vector<int> vv[MAX],ans;//1~n代表行 n+1~2*n代表列。 bool topu() {int tot = 0;ans.clear();priority_queue<int,vector<int> , greater<int> > pq;for(int i = 1; i<=2*n; i++) {if(in[i] == 0) pq.push(i);}while(pq.size()) {int cur = pq.top();pq.pop();tot++;if(vis[cur] != n) ans.pb(cur);int up = vv[cur].size();for(int i = 0; i<up; i++) {int v = vv[cur][i];in[v]--;if(in[v] == 0) pq.push(v); }}if(tot<2*n) return 0;else return 1; } int main() {int t;cin>>t;while(t--) {scanf("%d",&n);for(int i = 1; i<=2*n; i++) vv[i].clear(),vis[i]=0,in[i]=0;for(int i = 1; i<=n; i++) {scanf("%s",s+1);for(int j = 1; j<=n; j++) {if(s[j] == 'X') vv[n+j].pb(i),vis[n+j]++,in[i]++;else vv[i].pb(n+j),vis[i]++,in[n+j]++;}}bool flag = topu(); if(flag == 0) {puts("No solution");continue;}int up = ans.size();for(int i = 0; i<up; i++) {if(ans[i]>n) printf("C%d%c",ans[i]-n,i == up-1?'\n':' ');else printf("R%d%c",ans[i],i == up-1?'\n':' ');}}return 0 ; }?
總結
以上是生活随笔為你收集整理的【ZOJ - 3780】Paint the Grid Again(拓扑排序,图论,证明性质)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sonytray.exe - sonyt
- 下一篇: 【HihoCoder - 1502】最大