电子学会六级-数据结构-链表

破损的键盘
https://www.luogu.com.cn/problem/UVA11988

#include<bits/stdc++.h>

const int N = 100000+5;
int last, cur, next[N];
char s[N];

int main(){
	while(scanf("%s",s+1)==1){
		int n=strlen(s+1);
		last = cur = 0;
		next[0] = 0;
		
		for(int i = 1; i <= n; i++) {
			char ch = s[i];
			if(ch =='[') cur = 0;//遇到左括号 括号里面从0开始 放最前面 
			else if(ch==']') cur = last;//接在括号前面的字母后 
			else {
				next[i] = next[cur];//记录前一个位置 
				next[cur] = i;//记录当前位置 
				if(cur == last) last = i;//出现左括号 cur和last不相等 出现胡括号后再次相等 
				cur = i;
			}
		}
		
		for(int i = next[0]; i != 0; i = next[i])//从头指针 开始遍历 
			printf("%c", s[i]);
		printf("\n");
	}
	return 0;
}

移动盒子
https://www.luogu.com.cn/problem/UVA12657

队列安排
https://www.luogu.com.cn/problem/P1160

构造双链表

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct node{
    int L,R;
}a[100005];
int n, m;
//双向链表增加在右侧有节点 
inline void addRight(int x, int pos) { //x号同学插入pos同学右边 
    a[x].L=pos;//x左指向pos
    a[a[pos].R].L=x;//pos当前右q的左指向x --断掉当前pos的右的左 
    a[x].R=a[pos].R;//x的右指向pos的右  --断掉post的右 
    a[pos].R=x;//当前pos的右指向x 
}
//双链表在左侧增加节点 
inline void addLeft(int x,int pos) { //x号同学插入pos同学左边
    a[x].R=pos;//x的右指向pos 
    a[a[pos].L].R=x;//pos的前一个的右指向x 
    a[x].L=a[pos].L;//x的左指向post的左 
    a[pos].L=x;//pos的左指向x 
}

//双链表增加节点 
inline void del(int x) {
    if(a[x].L==-1) return;//如果左指针为-1 说明不存在此节点 
    a[a[x].L].R=a[x].R;//前面一个指向自己的下一个 
    a[a[x].R].L=a[x].L;//后面一个指向自己的前一个  27 28 断掉其他指向x的指针 
    a[x].L =-1;
    a[x].R =-1;//29 30 这两行断掉x指向其他 
}
//遍历输出 
inline void output() {
    int x = a[0].R;//从head 0开始 
    while(1) {
        cout<<x<<" ";
        if(a[x].R==-1) break;//右边为-1结束 
        x=a[x].R;
    }
}
inline void init() {//构建链表 
    for(int i=1;i<=n;i++){
    	a[i].L=a[i].R=-1;
	}
	a[1].L=0;//队列初始化一个人 a[1] 
	a[0].R=1;
}
int main(){
    scanf("%d", &n);//n个节点 
    int k,p;//k插入到哪个点的左面或者右面 p左面还是右面 0左面 1 右面 
    init();//初始双链表 
    for(int i=2; i<=n;i++){//从第2个同学开始插入 
        scanf("%d %d", &k,&p);//读入k p 
        if(!p) addLeft(i,k);//0 插入左面 
        else addRight(i,k);//1 插入右面 
    }
    scanf("%d",&m);//读入m 删除前m个数 
    for(int i=1;i<=m;i++) {
        scanf("%d",&k);
        del(k);//删除 
    }
    output();//遍历 
    return 0;
}

STL list

#include <bits/stdc++.h>
using namespace std;
bool vis[100005];
list<int> stus;//双向链表 
list<int>::iterator pos[100005];//迭代器访问list 
int main(){
    int n;
    scanf("%d",&n);//n个同学 
    stus.push_back(1);//list放入第一个元素 
    pos[1] = stus.begin();//获取开始位置迭代器 
    for (int i=2;i<=n;i++){
        int k,p;
        scanf("%d%d",&k,&p);//k插入到哪个点的左面或者右面 p左面还是右面 0左面 1 右面  
        if (p == 0){
            pos[i] = stus.insert(pos[k],i);//在post[k]位置左面插入i 
        }else{
            list<int>::iterator it = pos[k];
            ++it;
            pos[i] = stus.insert(it,i);//在post[k]位置右面插入i 
        }
    }
    int m = 0;
    scanf("%d",&m);//输入删除元素个数
    for (int i=0;i<m;i++){
        int x;
        scanf("%d",&x);//需要移除的同学 
        if (!vis[x]){
            stus.erase(pos[x]);
            vis[x] = true;
        }
    }
    for (list<int>::iterator i = stus.begin(); i != stus.end();i++){//迭代输出list 
        printf("%d ",*i);
    }
    return 0;
}

士兵队列训练问题
http://acm.hdu.edu.cn/showproblem.php?pid=1276

机器翻译
https://www.luogu.com.cn/problem/P1540

约瑟夫问题
https://www.luogu.com.cn/problem/P1996
循环链表

//循环链表实现。流程:数到这个人就把这个人从链表元素中删除并输出编号
#include<bits/stdc++.h>
using namespace std;
struct node{
    int data;
    node *next;
};
int n,m;
node *head,*p,*r;//head头指针 r尾指针 p当前指针 
int main(){
    scanf("%d %d",&n,&m);//输入n个人 数到m出列 
    if(m==0)m=n;//m为0 数到0就出等同与数到n
    head=new node;//申请空间
    head->data=1;//头节点数据置为1
    head->next=NULL;//头节点下一个为空
    r=head;//尾指针现在是头 头尾在一起 
    for(int i=2;i<=n;i++){
        p=new node;
        p->data=i;
        p->next=NULL;
        r->next=p;//把申请的新节点连到前面的链表上
        r=p;//尾指针后移一个 尾插法 
    }
    r->next=head;//尾指针指向头
    r=head;//循环链表建立完成
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m-2;j++)r=r->next;//循环到m的前两个人 方便后续删数据 
        cout<<r->next->data<<" ";//输出这第m个人的数据
        r->next=r->next->next;//跳过这个节点
        r=r->next;//新的一轮从上次的最后一个的下一个开始
    }
	return 0;
}

寄包柜
https://www.luogu.com.cn/problem/P3613
约瑟夫
https://www.luogu.com.cn/problem/P1145
循环数
https://www.luogu.com.cn/problem/P1467

posted @ 2022-04-25 22:00  new-code  阅读(15)  评论(0编辑  收藏  举报