地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5267

题意:Leo 有一个N*N 的格子,他又有一把魔法刷,这个刷子能把一行刷成黑色,一列刷成白色,每一行或每一列都只能刷一次。刚开始时,格子既不是白色,也不是黑色。

输入:题目给了刷好后的格子,其中'X'代表黑,’O’代表白。

输出:输出涂法。每一步用”R#”或”C#”表示,”#”指代数字,”R#”表示涂第’#行,”C#”表示涂第”#”列。输出时输出最小方案。最小方案是指:C<R,”#”也应该尽可能小。

思路:如果是一个有解的输入,那必然有一行或一列是同色的,即不过怎么涂,你最后一笔必然会使一行或一列同色。可以从这点出发,倒推,发现一行或一列同色时,使其还原为这一步之前的状态。

注意:因为是倒推,所以每一步都应优先取行,再取列,然后行号或列号应尽可能大,才能使之输出的序列最小。

关于还原上一步,如果用’-’表示没涂的状态,要考虑每个方格上一部的状态是’X’还是’O’,亦或是’-’;

举例说明:

输入     XX

OX

第一步:去第一行,

其中第一列有’O’,第二列没’O’,

所以可以化为:

O-

OX   //R1

第二步 :去第一列,

其中第一行没’X’,第二行有’X’

所以可以化为

- -

XX   //C1

第三步:去第二行,

其中第一列没’O’,第二列没’O’

所以可以化为

--

--  //R2

此时已经完成,逆序输出步骤即可

如果过程中不存在一行或一列是同色的,则可以判段此输入是非法的

/*
1500ms过的,一定还可以优化,
这次代码可能有点乱,请见谅
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <stack>
using namespace std; typedef struct node{
char dir;
int order;
}node; //用于表示步骤,dir代表R或C,order代表行号或列号 const int maxn = 500+20;
bool row[maxn], column[maxn]; //记录此行是否涂过,记录此列是否涂过
char map[maxn][maxn]; //输入的格子图
int N; inline void input() //输入
{
cin>>N;
int i,j;
for(i=0;i<N;i++)
{
getchar();
for(j=0;j<N;j++)
scanf("%c",&map[i][j]);
//cin>>map[i][j];
}
memset(row,false,sizeof(row));
memset(column,false,sizeof(column)); //数组初始化
return ;
} int judge() //判断是否已经回到最初的状态
{
int i,j;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
if( map[i][j]!='-' )
return 1;
return 0;
} inline void paint()
{
stack <node> st; //存储步骤
int i,j,k;
int flag=0; //记录有没有找到一行或一列同色
node t;
//int turn=0;
while( judge())
{
flag=0;
for(i=N-1;i>=0;i--) //行'X'
{
if(row[i])
continue;
for( j=0;j<N;j++ )
if(map[i][j]!='X') //是否有一行全部为‘X’
break;
if(j==N)
{
flag=1;
break;
}
} if(flag)
{
row[i]=true;
for(j=0;j<N;j++)
{
for(k=0;k<N;k++)
if( k!=i && map[k][j]=='O' )
break;
if( k==N )
map[i][j]='-';
else
map[i][j]='O'; //还原到上一步的状态
}
t.dir='R';
t.order=i;
st.push(t);
continue;
} flag=0;
//cout<<turn<<endl;
for(i=N-1;i>=0;i--) //列'O'
{
if(column[i])
continue;
for( j=0;j<N;j++ )
if(map[j][i]!='O') //是否有一列全部为‘O’
break;
if(j==N)
{
flag=1;
break;
}
} if(flag)
{
column[i]=true;
for(j=0;j<N;j++)
{
for(k=0;k<N;k++)
if( k!=i && map[j][k]=='X' )
break;
if( k==N )
map[j][i]='-';
else
map[j][i]='X'; //还原到上一步的状态
}
t.dir='C';
t.order=i;
st.push(t);
continue;
}
else
break; //没有找到一行或一列同色,退出
} //输出
if( judge() )
cout<<"No solution\n";
else
{
t=st.top();
st.pop();
printf("%c%d",t.dir,t.order+1);
while( !st.empty() )
{
t=st.top();
st.pop();
printf(" %c%d",t.dir,t.order+1);
}
printf("\n");
}
} int main()
{
int T;
cin>>T;
while(T--)
{
input();
paint();
}
return 0;
}

zoj p3780 Paint the Grid Again的更多相关文章

  1. 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 cel ...

  2. ZOJ 3781 Paint the Grid Reloaded(BFS+缩点思想)

    Paint the Grid Reloaded Time Limit: 2 Seconds      Memory Limit: 65536 KB Leo has a grid with N rows ...

  3. ZOJ 3781 Paint the Grid Reloaded(BFS)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 Leo has a grid with N rows an ...

  4. ZOJ 3781 - Paint the Grid Reloaded - [DFS连通块缩点建图+BFS求深度][第11届浙江省赛F题]

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 Time Limit: 2 Seconds      Me ...

  5. ZOJ 3780 - Paint the Grid Again - [模拟][第11届浙江省赛E题]

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3780 Time Limit: 2 Seconds      Me ...

  6. ZOJ 3780 Paint the Grid Again

    拓扑排序.2014浙江省赛题. 先看行: 如果这行没有黑色,那么这个行操作肯定不操作. 如果这行全是黑色,那么看每一列,如果列上有白色,那么这一列连一条边到这一行,代表这一列画完才画那一行 如果不全是 ...

  7. ZOJ 3781 Paint the Grid Reloaded(DFS连通块缩点+BFS求最短路)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5268 题目大意:字符一样并且相邻的即为连通.每次可翻转一个连通块X( ...

  8. ZOJ 3781 Paint the Grid Reloaded 连通块

    LINK:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 题意:n*m只由OX组成的矩阵,可以选择某一连通块变成另一 ...

  9. ZOJ 3781 Paint the Grid Reloaded

    枚举,$BFS$,连通块缩点. 可以枚举一开始染哪个位置,然后逐层往外染色,看最多需要多少操作次数,也就是算最短距离.连通块缩点之后可以保证是一个黑白相间的图,且每条边的费用均为$1$,$BFS$即可 ...

随机推荐

  1. MongoDB(三)mongoDB下载和安装

    软件下载 下载mongodb最新的包:http://www.mongodb.org/downloads 下载mongodb可视化界面,mongoVUE:http://download.csdn.net ...

  2. 【HDU】病毒侵袭持续中(AC自己主动机+map)

    一開始一直WA,之后发现这道题不止一组输入,改成多组输入之后就过了. 利用map把每一个字符串映射到它相应的结点上即可了. 11909467 2014-10-19 11:54:00 Accepted ...

  3. HDU1171:Big Event in HDU(多重背包分析)

    通过分析,要使A>=B并且差值最小.所以只要使sum/2的容量下,B最大就Ok了 #include<iostream> #include<cstdio> #include ...

  4. 托管服务帐号(Managed Service Account)

    托管服务帐号是绑定到单独的机器上,并且仅用于服务所用,所以不能用来登录. 创建托管帐号,不需要指定密码,密码会由活动目录自动管理.并且根据密码策略(默认30天)自动刷新,期间不影响服务. 在创建完之后 ...

  5. PHP冒泡排序法

    冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法.法如其名,就是像冒泡一样,每次从数组当中 冒一个最大的数出来. 冒泡排序它重复地走访过要排序的数列,一次比较两个元素,如果他 ...

  6. 3.PHP 教程_PHP 语法

     基础的PHP语法 PHP脚本可以放在文档中的任何位置. PHP脚本以<?php开始,以?>结束: <?php //PHP代码 ?> PHP文件的默认文件扩展名是". ...

  7. codeforces 557D. Vitaly and Cycle 二分图染色

    题目链接 n个点, m条边, 问最少加几条边可以出现一个奇环, 在这种情况下, 有多少种加边的方式. 具体看代码解释 #include<bits/stdc++.h> using names ...

  8. IOS 表视图(UITableVIew)的使用方法(6)表视图的编辑功能(新增Add)

    表视图的新增功能和删除功能虽然目的不同,但是工作流程是相似的 下面列出在处理新增的回调函数时,与删除所不同的逻辑部分代码. 显示下过如下: #pragma mark #pragma mark Tabl ...

  9. RFID电子标签制造封装工艺和可靠性研究

    一.目的和意义 电子标签已经成为RFID工业的主要焦点 实现低成本.大批量.高可靠性地制造电子标签是推广RFID产品应用的关键技术之一 针对RFID标签制造中核心的封装工艺开展研究,以各向异性导 ...

  10. (C#)Windows Shell 编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令

    原文(C#)Windows Shell 编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令 (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-) 接上一节:( ...