一开始没有思路自己强行用链表模拟了一下。
找到所有向右游的鱼,放进队列,每次处理它们向右走一步后的情况,分为4种:
1.右边的鱼向左&更小
链表中删掉右边的鱼,当前的鱼重新放回队列
2.右边的鱼向左&更大
链表中删掉当前的鱼
3.右边的鱼向左&大小相同
链表中交换两鱼的位置,当前的鱼重新放回队列
4.右边的鱼向右走
当前的的鱼重新放回队列
经粗略分析可知,当场景中还有大鱼能吃小鱼时,它们在n步内一定会吃到。我用sum记录没有吃到鱼的步数,在情况3&4是没有大鱼吃小鱼的,计数。碰到情况1&2是有大鱼吃小鱼,sum更新为0.当sum>=n时,说明已经没有大鱼能吃小鱼了,循环结束。
时间复杂度分析不出来(拿烟的手微微颤抖.jpg),反正我写的很复杂了。结构体指针用不顺,磨了两个小时才写完,虽然菜吧但是还挺有成就感的……
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
struct node{
int siz,dir;
node *pre,*ne;
};
queue<node*>q;
void print(node* head){//输出链表,测试用
node* now=head->ne;
while(1){
printf(" siz=%d dir=%d ne=%d\n",now->siz,now->dir,now->ne);
if(now->ne==NULL) break;
now=now->ne;
}
}
int main(){
while(!q.empty()) q.pop();
scanf("%d",&n);
node* head=(node*)malloc(sizeof(node));
node* tail=head;//?
for(int i=1;i<=n;i++){
node *tmp=(node*)malloc(sizeof(node));
int a,b;
scanf("%d%d",&a,&b);
tmp->siz=a;tmp->dir=b;tmp->pre=tail;tmp->ne=NULL;
tail->ne=tmp;tail=tmp;
}
node* now=head->ne;
while(1){
if(now->dir==1) q.push(now);
if(now->ne==NULL) break;
now=now->ne;
}
int sum=0,cal=n;
while(!q.empty()&&sum<=2*n){
node &tmp=*q.front();q.pop();
if(tmp.ne==NULL) continue;
if(tmp.ne->dir==0){
if(tmp.ne->siz<tmp.siz){
cal--;sum=0;
tmp.ne=tmp.ne->ne;
if(tmp.ne!=NULL)tmp.ne->pre=tmp.pre->ne;
q.push(&tmp);
}else if(tmp.ne->siz>tmp.siz){
cal--;sum=0;
tmp.ne->pre=tmp.pre;
tmp.pre->ne=tmp.ne;
}else{
if(tmp.ne->ne==NULL){
tmp.ne->pre=tmp.pre;
tmp.pre->ne=tmp.ne;
tmp.pre=tmp.ne;
tmp.ne->ne=&tmp;
tmp.ne=NULL;
}else{
tmp.ne->pre=tmp.pre;
tmp.ne->ne->pre=&tmp;
node *t=tmp.ne;
tmp.ne=tmp.ne->ne;
tmp.pre=t;
tmp.pre->pre->ne=tmp.pre;
tmp.pre->ne=&tmp;
}
q.push(&tmp);
sum++;
}
//print(head);
//printf("\n");
}else q.push(&tmp),sum++;
}
printf("%d\n",cal);
return 0;
}
/*
5
3 1
3 1
3 1
3 1
4 0
5
3 1
4 0
5 1
4 1
4 0
2
1 1 1 0
*/
然而看了题解之后,发现……emmmmm哭辽。栈的写法之后再补充吧。还有关于地址之类的优点小疑问你,先记录一下。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
int a;
node *ne;
};
queue<node>q;
int main(){
while(!q.empty()) q.pop();
node *H=(node*)malloc(sizeof(node));
node *n=(node*)malloc(sizeof(node));
H->ne=n;
H->a=1;
n->a=2;
printf(" %d\n",H->ne);
q.push(*n);
node &tmp=q.front();
printf(" %d\n",&tmp);
return 0;
}
/*
1.结构体放进queue再拿出来,地址相同吗?
2.结构体指针放进queue再拿出来,地址相同吗?
3.拿出时生命的变量带和不带&有什么区别?
*/