ZOJ 3780

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

2
2
XX
OX
2
XO
OX

Sample Output

R2 C1 R1
No solution

题目意思:给出n*n的方块图,初始时方块图颜色为空,给出图最终颜色,X表示黑色,O表示白色,Leo有一把刷子,只能横着刷或者竖着刷,横着刷为黑色,竖着刷为白色,问Leo能否刷成最终图的颜色。

思路:对每一次刷都是刷一行或者一列,那么从最终图向初始时倒着算,那么最后一次刷肯定是一行或者一列,找到这一行或者一列就删去正行或者整列,依次向前,若能把图删完那么倒着输出刷的顺序,否则输出No solution。  注意:该题说输出时按照字典序输出,那么每次尽可能先刷最下面的行或者最右边的列。

代码有点乱。。
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
using namespace std;

struct node{
    int mm;
    char c;
};

main()
{
    int t, n, i, j, k;
    stack<node>st;
    char map[505][505];
    cin>>t;
    while(t--){
        while(!st.empty()) st.pop();
        scanf("%d",&n);
        for(i=0;i<=n;i++){
            for(j=0;j<=n;j++) map[i][j]=‘X‘;
        }
        for(i=1;i<=n;i++) scanf("%s",map[i]+1);

        int num=0, u, f1, f2;
        while(num<n*n){
            for(i=n;i>=1;i--){             //行
                if(map[i][0]==‘.‘) continue;
                f1=1;
                for(j=1;j<=n;j++){
                    if(map[i][j]==‘.‘) continue;
                    if(map[i][j]!=‘X‘){
                        f1=0;break;
                    }
                }
                if(f1){
                    u=i;break;
                }
            }
            if(f1) {
                node p;
                for(j=1;j<=n;j++){
                    if(map[u][j]!=‘.‘) {
                        map[u][j]=‘.‘;num++;
                    }
                }

                p.c=‘R‘;p.mm=u;map[u][0]=‘.‘;
                st.push(p);continue;
            }
            int f2=1;
            for(j=n;j>=1;j--){             //列
                f2=1;
                if(map[0][j]==‘.‘) continue;
                for(i=1;i<=n;i++){
                    if(map[i][j]==‘.‘) continue;
                    if(map[i][j]!=‘O‘){
                        f2=0;break;
                    }
                }
                if(f2){
                    u=j;break;
                }
            }
            if(f2) {
                node p;
                for(i=1;i<=n;i++){
                    if(map[i][u]!=‘.‘) {
                        map[i][u]=‘.‘;num++;
                    }
                }

                p.c=‘C‘;p.mm=u;map[0][u]=‘.‘;
                st.push(p);continue;
            }
            if(!f1&&!f2) break;

        }
        if(num<n*n) printf("No solution\n");
        else{
            node p;
            p=st.top();st.pop();
            printf("%c%d",p.c,p.mm);
            while(!st.empty()){
                p=st.top();
                st.pop();
                printf(" %c%d",p.c,p.mm);
            }
            cout<<endl;
        }
    }
}
时间: 2024-10-27 20:42:25

ZOJ 3780的相关文章

ZOJ 3780 Paint the Grid Again(隐式图拓扑排序)

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 an

zoj 3780 Paint the Grid Again (拓扑排序)

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 an

ZOJ 3780 Paint the Grid Again(topsort)

ZOJ Problem Set - 3780 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

ZOJ 3780 E - Paint the Grid Again 拓扑排序

https://vjudge.net/problem/49919/origin 题意:给你n*n只出现O和X的字符阵.有两种操作,一种操作Ri将i行全变成X,一种操作Ci将i列全变成O,每个不同的操作最多进行一次.现给出目标状态,求空盘下的字典序最小的操作顺序是怎样的. 思路:拿到题目看起来很复杂,但仔细读题会发现X和O只由特定操作出现,且操作只进行一次,那么单独地考虑每行每列,如i行中出现了O,且存在X(如果不存在X那么可以略去Ri操作),说明在Ri操作后进行了Cj的操作,同样的方法去考虑列,

2014 Super Training #4 D Paint the Grid Again --模拟

原题:ZOJ 3780 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3780 刚开始看到还以为是搜索题,没思路就跳过了.结果后来发现就是一个简单的模拟啊,因为每行每列都只能消去一次,直接慢慢消去就好了,因为按字典序从小到大,那就按行从大到小,列从大到小的顺序来消就可以了,消完了标记一下,把那行或者那列的元素都赋为一个特殊的字符'*'即可. 还是应该多思考啊,不要被题目吓到了.探寻题目的本质才能更好的解题. 代码: #i

概率dp ZOJ 3640

Help Me Escape Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice ZOJ 3640 Appoint description:  System Crawler  (2014-10-22) Description Background     If thou doest well, shalt thou not be accepted? an

zoj 2156 - Charlie&#39;s Change

题目:钱数拼凑,面值为1,5,10,25,求组成n面值的最大钱币数. 分析:dp,01背包.需要进行二进制拆分,否则TLE,利用数组记录每种硬币的个数,方便更新. 写了一个 多重背包的 O(NV)反而没有拆分快.囧,最后利用了状态压缩优化 90ms: 把 1 cents 的最后处理,其他都除以5,状态就少了5倍了. 说明:貌似我的比大黄的快.(2011-09-26 12:49). #include <stdio.h> #include <stdlib.h> #include <

ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 最小生成树 Kruskal算法

题目链接:ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 Building a Space Station Time Limit: 2 Seconds      Memory Limit: 65536 KB You are a member of the space station engineering team, and are assigned a task in the construction process of the statio

ZOJ 3607 Lazier Salesgirl (贪心)

Lazier Salesgirl Time Limit: 2 Seconds      Memory Limit: 65536 KB Kochiya Sanae is a lazy girl who makes and sells bread. She is an expert at bread making and selling. She can sell the i-th customer a piece of bread for price pi. But she is so lazy