zoukankan      html  css  js  c++  java
  • 6.2 链表 (UVa 11988, 12657)

    掌握链表的删除,插入,遍历。可以用数组来构造链表。

    例题 6-4

    题目:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=838&page=show_problem&problem=3139

    思路:以单个字符为结点,构造链表,遇到 ' [ ' 字符时,接下来的输入就在开头插入,遇到 ' ] ' 字符时,接下来的输入就在结尾插入。

    代码:

    /* Broken Keyboard (UVa 11988) */
    #include<iostream>
    #include<cstring>
    //#define LOCAL
    using namespace std;
    int main(){
    #ifdef LOCAL
        freopen("input.txt","r",stdin);
        //freopen("output.txt","w",stdout);
    #endif
        int cur,last; //cur为当前指针指向的字符,last为[之前的最后一个字符
        char str[100005]; //存放字符串
        int next[100005]; //下一个字符的下标,形成链表,0为头结点
        while(scanf("%s",str+1)!=EOF){
            int len=strlen(str+1);   //注意是str+1 
            cur=0; last=0;
            memset(next,0,sizeof(next));
            for(int i=1;i<=len;i++){
                if(str[i]=='[')    //如果遇到 '[' ,就将当前指针指向头指针
                    cur=0;
                else if(str[i]==']') //如果遇到 ']' ,就将当前指针指向上一个'['前的最后一个字符(最外层的'['),即链表中最后一个字符 
                    cur=last;
                else{
                    //cout<<i<<endl;
                    //即将第i个字符插入当前指向的字符的后面
                    next[i]=next[cur];
                    next[cur]=i;
                    //更新cur和last
                    if(cur==last)
                        last=i;
                    cur=i; 
                } 
            }
            //输出链表
            for(int i=0;next[i]!=0;){
                i=next[i];
                printf("%c",str[i]);
            } 
            cout<<endl;
            memset(str,0,sizeof(str));
        } 
        return 0;
    }

    例题 6-5

    题目:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=838&page=show_problem&problem=4395

    思路:使用双向链表,灵活运用 link(a, b) 函数,将 x 移动到 y 的左边时,就 link(x_left, x_right), link(y_left, x), link(x, y), 注意,当反转链表时,相对方向也要改变,还要注意交换相邻的两个节点时的情况。

    代码:

    /* Boxes in a Line (UVa 12657) */
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    const int maxn = 100005;
    
    int Left[maxn], Right[maxn];            
    int *front = Left, *back = Right;        //前、后。 
    int n, m;
    
    void init();
    void link(int a, int b);    //连接 a 点和 b 点,a 在 b 之“前” 
    void output();                //调试,输出当前序列 
    
    int main(){
        //freopen("input.txt", "r", stdin);
        int kase = 0;
        while(cin >> n >> m){
            init();
            for(int i=0; i<m; i++){
                int x, y, z;
                cin >> x;
                if(x == 4){
                    swap(front, back);
                    continue;
                }
                cin >> y >> z;
                if(x == 1){
                    link(front[y], back[y]);
                    link(front[z], y);
                    link(y, z);
                }
                if(x == 2){
                    link(front[y], back[y]);
                    link(y, back[z]);
                    link(z, y);
                }
                if(x == 3){
                    int front_y = front[y], back_y = back[y], front_z = front[z], back_z = back[z];
                    if(front[y] == z){                    //注意相邻情况 
                        link(z, back_y);
                        link(front_z, y);
                        link(y, z);
                    }else if(front[z] == y){
                        link(y, back_z);
                        link(front_y, z);
                        link(z, y);
                    }else{
                        link(front_y, z);
                        link(z, back_y);
                        link(front_z, y);
                        link(y, back_z);
                    }
                }
            }
            int t = 0;
            long long sum = 0;
            for(int i=1; i<=n; i++){
                t = back[t];
                if(i%2 == 1)
                    sum += t;
            }
            //output();
            cout << "Case " << ++kase << ": "<< sum << endl;
        }
    }
    
    void init(){
        
        front = Left;    back = Right;
        memset(Left, 0, sizeof(Left));
        memset(Right, 0, sizeof(Right));
        for(int i=1; i<n; i++){
            link(i, i+1);
        }
        link(0, 1);
        link(n, 0);
        
    }
    
    void link(int a, int b){
        
        back[a] = b;
        front[b] = a;
        
    }
    
    void output(){
        int t = 0;
        for(int i=0; i<n; i++){
            t = back[t];
            cout << t << " ";
        }
        cout << endl;
    }
  • 相关阅读:
    使用公用表表达式的递归查询
    cocos2d-x 精灵的创建和基本使用
    全栈project师的毁与誉
    使用zTree和json构建简单树节点
    使用贝赛尔曲线画扇形、圆形、弧线、多边形,实现App下载时的动画效果demo
    UIBezierPathStudyDemo
    iOS-swift环形进度指示器+图片加载动画
    IOS之以UIBezierPath绘制饼状图
    Swift之UIBezierPath
    swift app中展示折线图, 饼状图, 柱状图等数据图表
  • 原文地址:https://www.cnblogs.com/lighter-blog/p/6118898.html
Copyright © 2011-2022 走看看