c++基础数据结构之栈、队列、链表
队列
1 2 3 4 5 6 7
| queue<int>q q.pop() q.push() q.front() q.rear() q.size() q.empty()
|
栈
1 2 3 4 5 6
| stack<int>st st.pop() st.push() st.top() st.size() st.empty()
|
1.单链表(注意结构体写法)
题目描述
实现一个单链表,链表初始为空,支持三种操作:
(1) 向链表头插入一个数;
(2) 删除第k个插入的数后面的数;
(3) 在第k个插入的数后插入一个数
现在要对该链表进行M次操作,进行完所有操作后,从头到尾输出整个链表。
注意:题目中第k个插入的数并不是指当前链表的第k个数。例如操作过程中一共插入了n个数,则按照插入的时间顺序,这n个数依次为:第1个插入的数,第2个插入的数,…第n个插入的数。
https://www.ixigua.com/7241418740699824643
输入格式
第一行包含整数M,表示操作次数。
接下来M行,每行包含一个操作命令,操作命令可能为以下几种:
(1) “H x”,表示向链表头插入一个数x。
(2) “D k”,表示删除第k个输入的数后面的数(当k为0时,表示删除头结点)。
(3) “I k x”,表示在第k个输入的数后面插入一个数x(此操作中k均大于0)。
输出格式
共一行,将整个链表从头到尾输出。
数据范围
1≤M≤100000
所有操作保证合法。
输入样例 复制
1 2 3 4 5 6 7 8 9 10 11
| 10 H 9 I 1 1 D 1 D 0 H 6 I 3 6 I 4 5 I 4 5 I 3 4 D 6
|
输出样例 复制
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| #include<iostream> using namespace std; struct node { int num; int time; node* next; }; node* head = new node(); void headin(int n,int i){ node* p=new node(); p->num=n; p->time=i;
p->next=head->next; head->next=p; } void de(int t){ node* p, * q; p=head->next; if(!t){ head->next=p->next; delete(p); } else{ while(p){ if(p->time==t)break; p=p->next; } q=p->next; p->next=q->next; delete(q); } } void insert(int t,int n,int i){ node* p=head->next; node* q=new node(); q->num=n; q->time=i; while(p){ if(p->time == t)break; p=p->next; } q->next=p->next; p->next=q; }
int main(){ head->next=NULL; int m,i,x,k; char op; i=1; cin>>m; while(m--){ cin>>op; if(op=='H'){ cin>>x; headin(x,i); i++; } if(op=='D'){ cin>>k; de(k); } if(op=='I'){ cin>>k>>x; insert(k,x,i); i++; } } node* p = head->next; while(p){ cout<< p->num << ' '; p=p->next; } }
|
2.简单计算器
题目描述
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
https://www.ixigua.com/7213692123635024436
输入格式
每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。
100 * 2 + 100 / 2 - 100 * 2 - 4 / 2
输出格式
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
输入样例 复制
输出样例 复制
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| #include<iostream> #include<stack> using namespace std; stack<double>d_st; stack<char>op_st;
int level(char a){ if(a=='+'||a=='-')return 1; if(a=='*'||a=='/')return 2; } void cal(){ char c=op_st.top();op_st.pop(); double a,b; a=d_st.top(); d_st.pop(); b=d_st.top(); d_st.pop(); if(c=='+')d_st.push(b+a); if(c=='-')d_st.push(b-a); if(c=='*')d_st.push(b*a); if(c=='/')d_st.push(b/a); } int main(){ string str; double x; getline(cin,str); int len=str.size(); for(int i=0;i<len;i++){ if(str[i]>='0' && str[i]<='9'){ x=str[i]-'0'; while(str[i+1]>='0' && str[i+1]<='9'){ x=x*10+str[i+1]-'0'; i++; } d_st.push(x); } else if(str[i]=='+' || str[i]=='-' || str[i]=='*' || str[i]=='/'){ if(op_st.empty()||level(str[i])>level(op_st.top())){ op_st.push(str[i]); } else if(!op_st.empty() && level(str[i])<=level(op_st.top())){ while(!op_st.empty() && level(str[i])<=level(op_st.top())){ cal(); } op_st.push(str[i]); } } } while(!op_st.empty()){ cal(); } printf("%.2lf",d_st.top()); }
|
3.约瑟夫环(队列解法)
题目描述
有n(n<100)个人依次围成一圈,从第1个人开始报数,数到第m个人出列,然后从出列的下一个人开始报数,数到第m个人又出列,…,如此反复到所有的人全部出列为止。设n个人的编号分别为1,2,…,n,打印出列的顺序。
输入格式
n和m。
输入样例
输出样例
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include<iostream> #include<queue> using namespace std; int main(){ queue<int>qe; int n,m; cin>>n>>m; for(int i=1;i<=n;i++){ qe.push(i); } while(!qe.empty()){ int x; for(int i=1;i<=m-1;i++){ x=qe.front(); qe.pop();qe.push(x); } x=qe.front();qe.pop(); cout<<x<<" "; } }
|
4.走出迷宫(bfs)
题目描述
当你站在一个迷宫里的时候,往往会被错综复杂的道路弄得失去方向感,如果你能得到迷宫地图,事情就会变得非常简单。
假设你已经得到了一个n*m的迷宫的图纸,请你找出从起点到出口的最短路。
视频讲解:https://www.ixigua.com/7166253132702450212
输入格式
第一行是两个整数n和m(1≤n,m≤100),表示迷宫的行数和列数。
接下来n行,每行一个长为m的字符串,表示整个迷宫的布局。字符‘.’表示空地,‘#’表示墙,‘S’表示起点,‘T’表示出口。
输出格式
输出从起点到出口最少需要走的步数。
输入样例
输出样例
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include<iostream> #include<queue> using namespace std; char a[105][105]; int vis[105][105]; int n,m; struct node{ int r,c; int step; };
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; void bfs(int sr,int sc,int er,int ec){ queue<node>qe; node q,t; q.r=sr,q.c=sc; q.step=0; qe.push(q); vis[q.r][q.c]=1; while(!qe.empty()){ q=qe.front(); qe.pop(); if(q.r==er && q.c==ec){ cout<<q.step; break; } for(int i=0;i<4;i++){ t.r=q.r+dir[i][0]; t.c=q.c+dir[i][1]; if(a[t.r][t.c]=='.' && vis[t.r][t.c]==0 && t.r>=1&&t.r<=n && t.c>=1&&t.c<=n){ t.step=q.step+1; vis[t.r][t.c]=1; qe.push(t); } } } }
int main(){ int sr,sc,er,ec; cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ cin>>a[i][j]; if(a[i][j]=='S')sr=i,sc=j; if(a[i][j]=='T')er=i,ec=j,a[i][j]='.'; } bfs(sr,sc,er,ec); }
|
5.出入栈判断
题目描述
现有 a∼z 26 个小球模拟出入栈操作,小球按照 a∼z 的顺序压入栈,在栈顶的元素可以随时被取出,在游戏开始前给出任意 26 个字母的一些排列,问是否能够由出栈顺序得到这个排列。
输入格式
输入第一行表示一个整数n, n<=100
接下来输入n行,每行表示一个a~z的排列。
输出格式
每组数据输出一行结果,如果能够由出栈顺序得到给定排列,则输出 yes,否则输出 no。
输入样例 复制
1 2 3
| 2 abcdefghijklmnopqrstuvwxyz zabcdefghijklmnopqrstuvwxy
|
输出样例 复制
数据范围与提示
5
abcdegfhijklnmopqrstuvwxyz
abcdegfhijklnmopqrstzyxwvu
dcbaegfhijklnmopqrstuvwxyz
abcdegfhijkwxyzlnmopqrstuv
abcdegfhijklnmouvwxyztsrqp
yes
yes
yes
no
yes
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include<bits/stdc++.h> using namespace std; int main(){ stack <char> st; int n; cin>>n; while(n--){ string s; cin>>s; int len=s.size(),j=0; for(int i=0;i<len;i++){ char ch=i+'a'; st.push(ch); while(!st.empty() && st.top()==s[j]){ st.pop(),j++; } } if(j==len)cout<<"yes\n"; else cout<<"no\n"; } }
|