uva 11988 uva 12657 数组模拟链表

//提前声明 此为写者的思路 可能读者读来有那么不解 慢慢体会吧 一起加油

uva11988 破碎的键盘
直接分析,给出一个字符串,我们先想到遇见【移动字符串,如果这个字符串很长,那么它的移动速度将会很慢,想想肯定就超时,那么如何节省时间的移动,我们就用链表来模拟移动,用数组的方式模拟链表移动。对于链表,我们首先要清楚就基本链表而言清楚链表,这样才能套用到数组的模拟之上。(清楚链表的基本结构,插入一个结点的方式等。。。)因此,我们结合题意不难想到cur光标位置出现的合理性,即用来标记前次的位置,即这次应当链接在哪段之后,则不遇见【和】的情况下的数组链表不难模拟出来。那么我们遇见【该如何呢,更印证cur光标的必然性,即改cur=0;别忘了还要将这链尾实现链接//此乃链表常识,再不断结合题意,last标记便易想出,此题即可解。
除此解法外,stl的list是真的强,与模拟数组相比,简直就是通俗易懂的典范代表。不能再典范了。

#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
using namespace std;
int main()
{
    
    char s[100005];
    while(scanf("%s",s+1)!=EOF)
    {
        
        int next[100005]={0};
        int last=0;
        next[0]=0;
        int l=strlen(s+1);
        int cur=0;
        for(int i=1;i<=l;i++)
        {
            char ch=s[i];
            if(ch=='['){
                cur=0;
            }
            else if(ch==']'){
                cur=last;
            }
            else {
                next[i]=next[cur];
                next[cur]=i;
                if(cur==last)
                    last=i;
                cur=i;
            }
        }
        for(int i=next[0];i!=0;i=next[i])
            printf("%c",s[i]);
        printf("\n");
    }
    return 0;
}

uva 12657 移动盒子
真心而言,明白上一题,这一题双向链表还是比较好想的,至于那刘汝佳的算法,真的是值得学习掌握的一种方法,它不仅仅只是这一道题的解法,更是一种解题的思路,化繁为简的思虑。值得细品。

#include <iostream>
#include <cstdio>
using namespace std;
int lef[100005];
int righ[100005];
void link(int x,int y){
    righ[x]=y;
    lef[y]=x;
}
int main()
{
    int kase=0;
    long long n,m;
    while(cin>>n>>m){
        for(int i=1;i<=n;i++){
            lef[i]=i-1;
            righ[i]=i+1;
        }
        righ[n]=0;
        righ[0]=1;
        lef[0]=0;
        int inv=0;
        int op,x,y;
        for(int i=0;i<m;i++){
            scanf("%d",&op);
            if(op==4) {
                inv=!inv;
                continue;
            }
            scanf("%d%d",&x,&y);
            if(inv&&op!=3) op=3-op;
            if(op==1&&righ[x]==y) continue;
            else if(op==2&&lef[x]==y) continue;
            int lx=lef[x],rx=righ[x],ly=lef[y],ry=righ[y];
            if(op==1){
                link(lx,rx);link(ly,x);link(x,y);
            }
            else if(op==2){
                link(lx,rx);link(y,x);link(x,ry);
            }
            else if(op==3){
                if(righ[x]==y){
                    link(lx,y);link(y,x);link(x,ry);
                }
                else if(righ[y]==x){
                    link(ly,x);link(x,y);link(y,rx);
                }
                else{
                link(lx,y);link(y,rx);link(ly,x);link(x,ry);
                }
            }
        }
        printf("Case %d: ",++kase);
        long long int sum=0;
        int d=0;
        for(int i=1;i<=n;i++){
            d=righ[d];
            if(i%2!=0){
                sum+=d;
            }
        }
        if(inv&&n%2==0){
            long long int sum2;
            sum2=(n+1)*n/2;
            sum=sum2-sum;
        }
        printf("%lld\n",sum);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值