RC-u4 拆积木
给定一个由带编号的积木搭成的长方体。其中每块积木的厚度都一样,由若干个单位边长的相邻方块组成(相邻是指两个方块有一面重合)。现在要求将这个长方体中的积木一块一块拆掉。每块积木只能从顶端取出,并且取出时不能移动还在长方体中的其它积木。请你给出一个拆积木的顺序。当然这种顺序可能是不唯一的,我们规定当有多种选择时,总是取出编号最小的那个。
输入格式
输入第一行给出两个正整数 N 和 M(1≤N,M≤1000),分别为长方体的高度和宽度。随后 N 行,每行给出 M 个整数,为对应位置上积木的编号。编号为不超过 10
6的正整数,数字间以空格分隔。题目保证不同积木的编号是不同的。
输出格式
在一行中输出按照题目限定可以拆卸积木的顺序。数字间以 1 个空格分隔,行首尾不得有多余空格。如果拆卸到某一步发现无法继续了,则在对应位置上输出 Impossible,然后结束。
输入样例1:
5 5
4 4 4 11 11
9 9 4 2 1
9 5 4 4 4
7 3 3 6 10
8 8 8 10 10
输出样例1:
11 1 2 4 6 9 5 3 7 8 10
输入样例2:
4 3
8 9 7
4 4 4
5 6 4
1 4 4
输出样例2:
7 8 9 Impossible
#include <bits/stdc++.h>
using namespace std;
const int MAX_N=1005;
int mp[MAX_N][MAX_N];
bool zhuank[MAX_N][MAX_N];
int N,M;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
bool vis[MAX_N][MAX_N];
bool k=true;
void bianli(int x,int y){
vis[x][y]=true;
if(zhuank[x-1][y]&&mp[x][y]!=mp[x-1][y]){
k=false;
return ;
}
for(int i=0;i<4;i++){
int a=x+dx[i];
int b=y+dy[i];
if(a<1||a>N||b<1||b>M) continue;
if(mp[a][b]!=mp[x][y]) continue;
if(!vis[a][b]) bianli(a,b);
}
}
void qingkong(int x,int y){
zhuank[x][y]=false;
for(int i=0;i<4;i++){
int a=x+dx[i];
int b=y+dy[i];
if(a<1||a>N||b<1||b>M) continue;
if(mp[a][b]!=mp[x][y]) continue;
if(zhuank[a][b]) qingkong(a,b);
}
}
int main(){
cin>>N>>M;
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
cin>>mp[i][j];
zhuank[i][j]=true;
}
}
while(1){
int choice=1e6+5;
int cx=0,cy=0;
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
k=true;
memset(vis,false,sizeof(vis));
bianli(i,j);
if(zhuank[i][j]&&k){
if(mp[i][j]<choice){
choice=mp[i][j];
cx=i;
cy=j;
}
}
}
}
if(choice==1e6+5){
cout<<"Impossible";
return 0;
}
qingkong(cx,cy);
bool cheng=true;
for(int a=1;a<=M;a++){
if(zhuank[N][a]){
cheng=false;
break;
}
}
if(cheng){
cout<<mp[cx][cy];
return 0;
}else{
cout<<mp[cx][cy]<<" ";
}
}
return 0;
}