【学习笔记】p 7912【CSP-J 2021】小熊的果篮——解题
题目传送门
正解
思路
打开两个链表,维护单个水果和每个区块最左边的部分,模拟暴力。
困难在于合并每个块最左边的部分。
让当前要删除的位置为“现在”,然后:
现在前体的后续处理:
如果NOW没有前兆:那为什么还要烦他,直接跳过就好。
如果NOW有前任但没有继任者:前任将没有继任者,指向END。
如果NOW有前任却只有一个继任者:不难证明继任者会和前任合并,合并后的前任不会有继任者,所以指向END。
如果NOW有前任但有两个或两个以上的继任者:类似于iii,但合并后仍会有继任者,这个继任者就是NOW的继任者。
NOW后续前驱体的处理:
实际上,如果且仅当NOW没有前兆,它将指向START,其他一切保持不变。
现在的继任者前任的处理:
假设它存在,那么:
如果NOW没有前身:那显然应该是NOW的继承者。
如果NOW有前兆:显然应该是NOW的前兆。
以上三个部分整合成三个订单的几个集合。
代码
#包括牡蛎
#includecstdio
#包括算法
# includecstring
使用命名空间标准;
const int Hen _ Hen _ EAA aa(233333);
吃东西
int Now,Nxt,Bef,Col//职位、前驱和后继
}吃[Hen_hen_eaaaaa],frt[Hen _ Hen _ eaaaaa];
int n,cnt,STT;
bool NOW//当前水果(用于构建不同的块
内联int(R){ 0
int x=0,f=1;char c=' c
while(c ' 9 ' | | c ' 0 '){ f=f *(c=='-'-1:1);c=getchar();}
while(c=' 9 ' c=' 0 '){ x=x * 10 c-' 0 ';c=getchar();}
返回x * f;
}
int main(){ 0
n=R();
if(!n)返回0;
for(int I=1;I=n;i){frt[i]。col=R();frt[i]。bef=I-1;frt[i-1]。NXT=I;}
现在=!frt[1]。Colfrt[0]。NXT=1;
for(int I=1;I=n;I){ 0
if(frt[i]。上校!=NOW){ 0
NOW=frt[i]。Col
吃。now=I;
吃。bef=CNT-1;
吃[cnt-1]。Nxt=cnt
}
}
NNN;
while(frt[0]。NX乳头[0]。NXT){ 0
n=吃[0]。Nxt
而(N){ 0
printf('%d ',吃[N]。现在);
NN=吃[N]。现在;
frt[frt[NN]。Bef]。Nxt=frt[NN]。Nxt
frt[frt[NN]。Nxt]。Bef=frt[NN]。Bef
吃[N]。Now=frt[NN]。Nxt
NNN=吃[N]。现在;
if(((frt[NNN])。上校!=frt[NN]。Col)||(!NNN吃。Bef]。现在】。上校!=frt[NN]。Col)||(!吃[N]。Bef))。
吃。Bef]。Nxt=(吃[N]。吃,吃。Nxt]。NXT et[N]。吃。Nxt). Nxt :0): eat[N]。NXT);
吃,吃。Nxt]。Nxt]。Bef=((吃[N]。吃饭前。Nxt]。NXT et[N]。吃,吃。Nxt]。Nxt]。bef);
吃。Nxt]。Bef=((吃[N]。Bef||!吃[N]。吃。NXT】. bef :0);
}//最难的合并操作
N=吃[N]。Nxt
}
printf(' \ n ');
}
返回0;
}
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/74731.html