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 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
/*
题意:一个矩阵有两种操作,将每行染成黑色,将每列染成白色每行,每列只能操作一次
现在给你特定的矩阵,最初的序列是什么颜色也没有的,问你至少操作几次才能形成
制定的矩阵 初步思路:对于单个元素来说,如果最后的颜色是黑色那么肯定是先进性染白色的操作,
然后进行的黑色操作,将行列信息建成图,然后用拓扑排序,进行排序并字典序输出 #错误:有一个点,就是最开始的入度为零的点,是不能操作的,因为这些点并没有状态转
化过来
*/
#include <bits/stdc++.h>
using namespace std;
vector<int>edge[];
int inv[];//表示每个点的入度
int t;
int n;
char mapn[][];
int frist[];//表示是不是第一个点
void topu(vector<int> &v){//用于存储操作的顺序
priority_queue<int,vector<int>,greater<int> >q;
for(int i=;i<n*;i++){//将所有的入度为零的点加入队列
if(inv[i]==){
q.push(i);
frist[i]=;
}
}
while(!q.empty()){
int x=q.top();
v.push_back(x);
q.pop();
for(int i=;i<edge[x].size();i++){
int Next=edge[x][i];
inv[Next]--;//将于这个点相关的边都删掉
if(inv[Next]==){//如果入度为零了那么加进队列
q.push(Next);
}
}
}
for(int i=;i<n*;i++){
if(inv[i]){
v.clear();
break;
}
}
}
void init(){
for(int i=;i<;i++){
edge[i].clear();
}
memset(inv,,sizeof inv);
memset(frist,,sizeof frist);
}
int main(){
// freopen("in.txt","r",stdin);
scanf("%d",&t);
while(t--){
init();
scanf("%d",&n);
for(int i=;i<n;i++){
scanf("%s",mapn[i]);
for(int j=;j<n;j++){//按照元素信息进行建图
if(mapn[i][j]=='O'){//如果最后的颜色是黑色的那么肯定是先进行列染白色的,然后进行行染黑
edge[i].push_back(n+j);
inv[n+j]++;
}else{//如果最后的颜色是白色,那么肯定是先进行 行染黑色,然后进行列染白色
edge[n+j].push_back(i);
inv[i]++;
}
}
}
//建好图了然后进行topu排序
vector<int>v;
v.clear();
topu(v);
if(v.size()==){
puts("No solution");
}else{
for(int i=;i<v.size()-;i++){
if(frist[v[i]]) continue;
if(v[i]>=n){
printf("C%d ",v[i]-n+);
}else{
printf("R%d ",v[i]+);
}
}
if(v[v.size()-]>=n){
printf("C%d\n",v[v.size()-]-n+);
}else{
printf("R%d\n",v[v.size()-]+);
}
}
}
return ;
}
Paint the Grid Again (隐藏建图+优先队列+拓扑排序)的更多相关文章
- 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序
题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足: Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆. 现在 ...
- POJ 3687 Labeling Balls 逆向建图,拓扑排序
题目链接: http://poj.org/problem?id=3687 要逆向建图,输入的时候要判重边,找入度为0的点的时候要从大到小循环,尽量让编号大的先入栈,输出的时候注意按编号的顺序输出重量, ...
- 模拟赛T2 线段树优化建图+tarjan+拓扑排序
然而这只是 70pts 的部分分,考场上没想到满分怎么做(现在也不会) code: #include <cstdio> #include <string> #include & ...
- HDU 4857 逃生 【拓扑排序+反向建图+优先队列】
逃生 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...
- bzoj5017 炸弹 (线段树优化建图+tarjan+拓扑序dp)
直接建图边数太多,用线段树优化一下 然后缩点,记下来每个点里有多少个炸弹 然后按拓扑序反向dp一下就行了 #include<bits/stdc++.h> #define pa pair&l ...
- POJ - 3249 Test for Job (在DAG图利用拓扑排序中求最长路)
(点击此处查看原题) 题意 给出一个有n个结点,m条边的DAG图,每个点都有权值,每条路径(注意不是边)的权值为其经过的结点的权值之和,每条路径总是从入度为0的点开始,直至出度为0的点,问所有路径中权 ...
- 2016 百度之星初赛 Gym Class(优先队列+拓扑排序)
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status Pract ...
- 图的拓扑排序,AOV,完整实现,C++描述
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- HDU 4857 逃生(反向建边的拓扑排序+贪心思想)
逃生 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submissi ...
随机推荐
- Unity 3D Time 类
Time class in UnityEngine Description The interface to get time information from Unity. Static Var ...
- windows7下MongoDB(V3.4)的使用及仓储设计
简单的介绍一下,我使用MongoDB的场景. 我们现在的物联网环境下,有部分数据,采样频率为2000条记录/分钟,这样下来一天24*60*2000=2880000约等于300万条数据,以后必然还会增加 ...
- Minutes和TotalMinutes的区别
今天测试提了一个BUG,说是消息提醒的时机不对,设置的提前2小时,还没到就提醒了. 看了下代码 (m.ExpectReceiveTime - DateTime.Now).Minutes < (p ...
- Prison Break
Prison Break 时间限制: 1 Sec 内存限制: 128 MB提交: 105 解决: 16[提交][状态][讨论版] 题目描述 Scofild又要策划一次越狱行动,和上次一样,他已经掌 ...
- spring框架总结(03)重点介绍(Spring框架的第二种核心掌握)
1.Spring的AOP编程 什么是AOP? ----- 在软件行业AOP为Aspect Oriented Programming 也就是面向切面编程,使用AOP编程的好处就是:在不修改源代码的情 ...
- PHP常用字符串处理函数
(1)strlen(string) 返回字符串长度 (2)strpos(string,find,begin) 返回find字符串第一次出现的位置(从0开始) string:处理的字符串 find:想找 ...
- python --- json模块和pickle模块详解
json:JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式(用于数据序列化和反序列化).(适用于多种编程语言,可以与其他编程语言做数据交换 ...
- 【懒人有道】在asp.net core中实现程序集注入
前言 在asp.net core中,我巨硬引入了DI容器,我们可以在不使用第三方插件的情况下轻松实现依赖注入.如下代码: // This method gets called by the runti ...
- 使用MxNet新接口Gluon提供的预训练模型进行微调
1. 导入各种包 from mxnet import gluon import mxnet as mx from mxnet.gluon import nn from mxnet import nda ...
- DevOps之内容分发网络CDN
唠叨话 关于德语噢屁事的知识点,仅提供专业性的精华汇总,具体知识点细节,参考教程网址,如需帮助,请留言. <内容分发网络CDN(Content Delivery Network)> 关于虚 ...