1 条题解

  • 0
    @ 2025-8-24 22:23:00

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar yxy666
    J O K E R

    搬运于2025-08-24 22:23:00,当前版本为作者最后更新于2021-01-02 21:23:36,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    看懂题目后,我们可以发现我们需要判断当前这个拼图的种类是根据上一块拼图的种类而决定的。

    如果上一块拼图的右边是凸进去的,那么我们就将有两个选择:3 号拼图和 4 号拼图。如果其中一种拼图用完了,那就用另外一种拼图呗。如果两种拼图都有,那么就看一下哪个编号小咯。但是选 4 号拼图的时候一个条件:得有 1 号拼图为它擦屁股;为什么呢?对于一开始凸的形状,如果最后不能还原成凸的形状,那么最后一块就无法装了。

    如果上一块拼图的右边是凹进去的,那么我们就将有两个选择:1 号拼图和 2 号拼图。如果其中一种拼图用完了,那就用另外一种拼图呗。如果两种拼图都有,那么就看一下哪个编号小咯。但是选 1 号拼图的时候一个条件:得有 4 号拼图为它擦屁股。为什么呢?对于一开始凹的形状,如果最后不能还原成凹的形状,那么最后一块就无法装了。

    还有一个问题:我们应该如何取每种拼图的最小编号呢?集合或者小根堆啊!

    code :

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=200005;
    int n,L,R,flg,cnt=1,hep[5][maxn],size[5],ans[maxn];
    inline int read(){
    	int ret=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch))ret=ret*10+ch-'0',ch=getchar();
    	return ret*f;
    }
    void put(int id,int x){
    	hep[id][++size[id]]=x;int son=size[id];
    	while(son>1&&hep[id][son]<hep[id][son/2])swap(hep[id][son],hep[id][son/2]),son/=2;
    }
    int get(int id){
    	int x=hep[id][1];int fa=1,son;hep[id][1]=hep[id][size[id]--];
    	while(fa*2<=size[id]){
    		if(fa*2+1>size[id]||hep[id][fa*2]<hep[id][fa*2+1])son=fa*2;else son=fa*2+1;
    		if(hep[id][son]<hep[id][fa])swap(hep[id][son],hep[id][fa]),fa=son;else break;
    	}
    	return x;
    	
    }
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++){
    		int x=read(),w=read();
    		if(x==5)ans[1]=w,L=0;
    		else if(x==6)ans[1]=w,L=1;
    		else if(x==7)flg=w,R=1;
    		else if(x==8)flg=w,R=0;
    		else put(x,w);
    	}
    	while(1){
    		if(L){
    			if(!size[1]&&!size[2])break;
    			else if(size[1]&&!size[2])ans[++cnt]=get(1),L=1-L;
                else if(!size[1]&&size[2])ans[++cnt]=get(2);
    			else{
    				if(!size[4]||(size[4]&&hep[2][1]<hep[1][1]))ans[++cnt]=get(2);
    				else ans[++cnt]=get(1),L=1-L;
    			}
    		}
    		else{
    			if(!size[3]&&!size[4])break;
    			else if(!size[4]&&size[3])ans[++cnt]=get(3);
    			else if(!size[3]&&size[4])ans[++cnt]=get(4),L=1-L;
    			else{
    				if(!size[1]||(size[1]&&hep[3][1]<hep[4][1]))ans[++cnt]=get(3);
    				else ans[++cnt]=get(4),L=1-L;
    			}
    		}
    	}
    	if(L==R&&!size[1]&&!size[2]&&!size[3]&&!size[4]){
    		ans[++cnt]=flg;
    		for(int i=1;i<=cnt;i++)printf(i==cnt?"%d\n":"%d ",ans[i]);
    	}
    	else printf("-1\n");
    	return 0; 
    }
    
    • 1

    信息

    ID
    5638
    时间
    1000ms
    内存
    500MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者