[链表模拟]51nod1289大鱼吃小鱼

一开始没有思路自己强行用链表模拟了一下。

找到所有向右游的鱼,放进队列,每次处理它们向右走一步后的情况,分为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.拿出时生命的变量带和不带&有什么区别?
*/

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值