[题解]P5462-X龙珠
观察题目,思考一下,很快可以知道,这题使用贪心即可。
题目要求求字典序最大的方案,则
越大的数字应该放在越前面,最大的数字放在最前面。
所以前面的要尽量大,我们这里以每次取出的两颗龙珠前者为准(因为他排在前边嘛)
题目规定各龙珠编号互不相同,那么最终摆放顺序直接就确定了。 从大到小排序,一波扫过来,如果未被取走一并取出与其相邻的下一颗龙珠,已经取走的就不管了,完事。
这里有个特殊点,最后一颗龙珠需要特判,因为她(?)没有下一颗龙珠与其作伴。
至于删除的问题,咱就直接链表啥的解决了吧。。。比赛的时候因为写不好链表罚分到自闭
(不会链表的可以先去看看)
程序的思路:
输入
这里我搞了一个pos用于储存一个数在原链表中的位置(因为编号各不相同)
下面是码,
#include<bits/stdc++.h>
using namespace std;
int N;
int a[1000005];//原数列(位置=>数值)
int b[1000005];//表示这个数是否已经被取走
int c[1000005];//排序好的数列
int pos[1000005];//记录位置(数值=>位置)
int n[1000005];//next记录链表结点的下一个节点位置
int l[1000005];//last记录链表结点的下一个节点位置
bool cmp(int x,int y) {//排序用的比较函数
return x>y;
}
int main() {
cin>>N;
for(int i=1; i<=N; i++) {
cin>>a[i];
pos[a[i]]=i;//位置
c[i]=a[i];//赋值
n[i]=i+1;//后继
l[i]=i-1;//前驱
}
n[N]=-1;//最后一个结点指向-1(无)
sort(c+1,c+1+N,cmp);//排序
for(int i=1; i<=N; i++) {
int k1,k2,p1,p2;//k为编号,p为位置
k1=c[i];//取出的前一个龙珠编号
p1=pos[k1];//前一个龙珠的位置
p2=n[p1];//后一个龙珠的位置(前者的下一个)
if(p2==-1)//如果这是最后一个龙珠是不能取下一个的
continue;
k2=a[p2];//后一个龙珠的值
if(!b[k1] && !b[k2]) {//如果没被取出
cout<<k1<<" "<<k2<<" ";//输出
b[k1]=1;
b[k2]=1;//标记
//删除2个相邻链表节点的操作:
n[l[p1]]=n[p2];//前者的下一个改成后者的下一个
l[n[p2]]=l[p1];//后者的上一个改成前者的上一个
}
}
return 0;//完事跑路
}
理解第一,通过第二。
『做正确,好懂,好看的题解』