您的位置:首页 > 大数据 > 人工智能

ZOJ - 3780-Paint the Grid Again-(拓扑排序)

2017-04-08 21:01 288 查看
DescriptionLeohasagridwithN×Ncells.Hewantstopainteachcellwithaspecificcolor(eitherblackorwhite).Leohasamagicalbrushwhichcanpaintanyrowwithblackcolor,oranycolumnwithwhitecolor.Eachtimeheusesthebrush,thepreviouscolorofcellswillbecoveredbythenewcolor.Sincethemagicofthebrushislimited,eachrowandeachcolumncanonlybepaintedatmostonce.Thecellswerepaintedinsomeothercolor(neitherblacknorwhite)initially.Pleasewriteaprogramtofindoutthewaytopaintthegrid.InputTherearemultipletestcases.ThefirstlineofinputcontainsanintegerTindicatingthenumberoftestcases.Foreachtestcase:ThefirstlinecontainsanintegerN(1<=N<=500).ThenNlinesfollow.EachlinecontainsastringwithNcharacters.Eachcharacteriseither'X'(black)or'O'(white)indicatesthecolorofthecellsshouldbepaintedto,afterLeofinishedhispainting.OutputForeachtestcase,output"Nosolution"ifitisimpossibletofindawaytopaintthegrid.Otherwise,outputthesolutionwithminimumnumberofpaintingoperations.Eachoperationiseither"R#"(paintinarow)or"C#"(paintinacolumn),"#"istheindex(1-based)oftherow/column.Useexactlyonespacetoseparateeachoperation.Amongallpossiblesolutions,youshouldchoosethelexicographicallysmallestone.AsolutionXislexicographicallysmallerthanYifthereexistsanintegerk,thefirstk-1operationsofXandYarethesame.Thek-thoperationofXissmallerthanthek-thinY.Theoperationinacolumnisalwayssmallerthantheoperationinarow.Iftwooperationshavethesametype,theonewithsmallerindexofrow/columnisthelexicographicallysmallerone.SampleInput
2
2
XX
OX
2
XO
OX

SampleOutput
R2C1R1
Nosolution
题意:
在一张空白的图上有两个操作:

·Rx将x行涂成黑色
·Cx将x列涂成白色
每行每列只能进行一次操作。
给定一个目标的图形,问至少需要几次操作才能达到目标图形,输出路径
分析:
一开始就想到了用图论来解决
我首先想到了如何建图:
由于每个点最多会被涂两次(R一次,C一次)。
由于R和C涂的颜色是不一样的,我们可以根据这个点的目标颜色判断出对这个点的这两次操作的先后顺序。
由此可以按先后顺序建一条边。
我们的目的就是求出一条路径满足所有这些条件(即拓扑排序)
最后题目要求字典序最小的方案,由于列变换字符'C'的字典序比行变换'R'的字典序小,因此把列号设为1~n,行号设为n+1~2n,而且要求变换的行列坐标也要最小,因此用最小堆的优先队列来代替普通队列进行拓扑排序,
另外注意一点,起点(第一个入度为0的点)是不用涂的。因为起点在后面涂的时候一定会被覆盖
比如单一个点'X',拓扑序为第1列->第1行,但是显然刷第1列这个操作是多余的。
代码:

#include<bits/stdc++.h>
usingnamespacestd;
constintMAXN=1030;
structedge
{
inte;
intnxt;
edge():nxt(0){};
edge(inte2,intnxt2):e(e2),nxt(nxt2){};
}e[MAXN*MAXN];
inthead[MAXN];
inttot;
intdeg[MAXN];
intn;
voidadd(intb,intee)
{
e[tot]=edge(ee,head[b]);
head[b]=tot++;
}
std::vector<int>res;
intnon[MAXN];
booltopo()
{
priority_queue<int,vector<int>,greater<int>>q;
for(inti=1;i<=2*n;i++){//!注意是2*n
if(deg[i]==0){
q.push(i);
//res.push_back(i);
//cout<<"push"<<i<<endl;
non[i]=1;
}
}
intt;
intnow;
while(!q.empty()){
t=q.top();
q.pop();
res.push_back(t);
for(inti=head[t];i!=0;i=e[i].nxt){
now=e[i].e;
deg[now]--;
if(!deg[now]){
q.push(now);
}
}
}
//cout<<"size"<<res.size()<<endl;
returnres.size()==n*2;//!注意是2*n
}
voidinit(){
memset(head,0,sizeof(head));
memset(deg,0,sizeof(deg));
tot=1;
res.clear();
memset(non,0,sizeof(non));
}
intmain()
{
//freopen("data.in","r",stdin);
intt;
scanf("%d",&t);
charch;
while(t--){
init();
scanf("%d",&n);
getchar();
for(inti=1;i<=n;i++){
for(intj=1;j<=n;j++){
ch=getchar();
if(ch=='X'){
add(j,i+n);deg[i+n]++;
}
else{
add(i+n,j);deg[j]++;
}
}
getchar();
}
if(!topo()){
printf("Nosolution\n");
}
else{
intnow=0;
intlen=res.size();
for(inti=0;i<len;i++){
now=res[i];
if(non[now])continue;
else{
printf("%c%d%c",now>n?'R':'C',now>n?now-n:now,i==len-1?'\n':'');
}
}
//printf("\n");
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
章节导航