2023 RoboCom 世界机器人开发者大赛-本科组(国赛) CAIP RC-u4 拆积木

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;
}

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值