入门经典_Chap06_例题[一]:队列,栈,链表的数组实现
来源:互联网 发布:淘宝数据分析哪些内容 编辑:程序博客网 时间:2024/06/05 18:39
前言
这一章的终极目的是巩固数据结构,尽可能地使用数组实现所有的数据结构,包括队列,栈,链表,二叉树等
题解如下
UVA - 210_Concurrency Simulator
思路
(书上的原话)你的任务是模拟n个程序(按输入顺序编号为1~n)的并行执行。每个程序包含不超过25条语句,格式一共有5种:var = constant(赋值);print var(打印);lock;unlock;end。
变量用单个小写字母表示,初始为0,为所有程序公有(因此在一个程序里对某个变量赋值可能会影响另一个程序)。常数是小于100的非负整数。
每个时刻只能有一个程序处于运行态,其他程序均处于等待态。上述5种语句分别需要t1、t2、t3、t4、t5单位时间。运行态的程序每次最多运行Q个单位时间(称为配额)。当一个程序的配额用完之后,把当前语句(如果存在)执行完之后该程序会被插入一个等待队列中,然后处理器从队首取出一个程序继续执行。初始等待队列包含按输入顺序排列的各个程序,但由于lock/unlock语句的出现,这个顺序可能会改变。
lock的作用是申请对所有变量的独占访问。lock和unlock总是成对出现,并且不会嵌套。lock总是在unlock的前面。当一个程序成功执行完lock指令之后,其他程序一旦试图执行lock指令,就会马上被放到一个所谓的阻止队列的尾部(没有用完的配额就浪费了)。当unlock执行完毕后,阻止队列的第一个程序进入等待队列的首部。输入n, t1, t2, t3, t4, t5, Q以及n个程序,按照时间顺序输出所有print语句的程序编号和结果。
使用队列模拟,要用到双端队列,这里用数组模拟的, 也可以使用STL里的deque
复杂点在于字符串的处理,和lock的处理
代码
#include <algorithm>#include <iostream>#include <sstream>#include <utility>#include <string>#include <vector>#include <queue>#include <map>#include <set>#include <cstring>#include <cstdio>#include <cmath>#define met(a,b) memset(a, b, sizeof(a));#define IN freopen("in.txt", "r", stdin);using namespace std;typedef long long LL;typedef pair<int, int> PII;const int maxn = 1e3 + 100;const int INF = 0x7fffffff;int n, a[6], Q;string s, str;vector<string> v[maxn];int curID[maxn], val[30];bool lock;int qw[maxn], wft, wrr;int qd[maxn], dft, drr;int main() { #ifdef _LOCAL IN; #endif // _LOCAL int t; cin >> t; while(t--) { wft = wrr = maxn/2; dft = drr = maxn/2; scanf("%d", &n); for(int i = 0; i < 5; ++i) scanf("%d", &a[i]); scanf("%d", &Q); for(int i = 1; i <= n; ++i) { v[i].clear(); while(getline(cin, s)) { if(s == "") continue; v[i].push_back(s); if(s == "end") break; } qw[wrr++] = i; } met(curID, 0); met(val, 0); lock = 0; while(wrr > wft) { int cur = qw[wft++]; int L = Q, tot = v[cur].size(); bool flag = 0; while(L > 0) { str = v[cur][curID[cur]]; if(str[2] == '=') { str[2] = ' '; stringstream ss(str); char aa; int b; ss >> aa >> b; val[aa - 'a'] = b; L -= a[0]; } else if(str[0] == 'p') { printf("%d: %d\n", cur, val[str[str.size()-1]-'a']); L -= a[1]; } else if(str[0] == 'l') { if(lock) { qd[drr++] = cur; flag = 1; break; } lock = 1; L -= a[2]; } else if(str[0] == 'u') { if(lock) { if(drr>dft) qw[--wft] = qd[dft++]; lock = 0; } L -= a[3]; } else { flag = 1; break; } ++curID[cur]; } if(! flag) qw[wrr++] = cur; } if(t) printf("\n"); } return 0;}
UVA - 514_ Rails
思路
模拟栈的水题,不解释
代码
#include <algorithm>#include <iostream>#include <sstream>#include <utility>#include <string>#include <vector>#include <queue>#include <map>#include <set>#include <cstring>#include <cstdio>#include <cmath>#define met(a,b) memset(a, b, sizeof(a));#define IN freopen("in.txt", "r", stdin);using namespace std;typedef long long LL;typedef pair<int, int> PII;const int maxn = 1e3 + 100;const int INF = 0x7fffffff;int n, a[maxn];int stake[maxn];int main() { #ifdef _LOCAL IN; #endif // _LOCAL while(scanf("%d", &n) == 1 && n) { while(scanf("%d", &a[0]) == 1 && a[0]) { for(int i = 1; i < n; ++i) scanf("%d", &a[i]); int cur = 1, top = 0; bool ok = 1; for(int i = 0; i < n; ++i) { if(top > 0 && a[i] == stake[top]) { --top; continue; } else { while(cur <= n && a[i] != cur) stake[++top] = cur, ++cur; if(cur > n) { ok = 0; break; } else ++cur; } } if(ok) printf("Yes\n"); else printf("No\n"); } printf("\n"); } return 0;}
UVA - 442_Matrix Chain Multiplication
思路
输入n个矩阵的维度和一些矩阵链乘表达式,输出乘法的次数。如果乘法无法进行,输出error。
假定A是m * n矩阵,B是n * p矩阵,那么AB是m * p矩阵,乘法次数为m * n * p。如果A的列数不等于B的行数,则乘法无法进行。
例如,A是50 * 10的,B是10 * 20的,C是20 * 5的,则(A(BC))的乘法次数为10 * 20 * 5(BC的乘法次数)+ 50 * 10 * 5((A(BC))的乘法次数)= 3500。
栈的应用:栈可以用于解析表达式!
代码
#include <algorithm>#include <iostream>#include <sstream>#include <utility>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <cstring>#include <cstdio>#include <cmath>#define met(a,b) memset(a, b, sizeof(a));#define IN freopen("in.txt", "r", stdin);using namespace std;typedef long long LL;typedef pair<int, int> PII;const int maxn = 1e3 + 100;const int INF = 0x7fffffff;int n, a, b;char c;string str;struct node { int r, c; node (){} node (int a, int b):r(a), c(b){}}e[30];stack<node> s;int main() { #ifdef _LOCAL IN; #endif // _LOCAL cin >> n; for(int i = 0; i < n; ++i) { getchar(); scanf("%c %d%d", &c, &a, &b); e[c-'A'] = node(a, b); } while(cin >> str) { int len = str.length(), ans = 0; for(int i = 0; i < len; ++i) { if(str[i] == '(') { } else if(str[i] == ')' ) { node ta = s.top(); s.pop(); node tb = s.top(); s.pop(); if(ta.r != tb.c) { ans = -1; break; } ans += tb.r*ta.r*ta.c; s.push(node(tb.r, ta.c)); } else s.push(e[str[i]-'A']); } if(ans == -1) printf("error\n"); else printf("%d\n", ans); } return 0;}
UVA - 11988_Broken Keyboard (a.k.a. Beiju Text)
思路
链表的数组实现,实用+方便
有一点个人领悟,使用链表的时候所有的数组最好下标都从1开始,给头指针留有余地。
代码
#include <algorithm>#include <iostream>#include <sstream>#include <utility>#include <string>#include <vector>#include <queue>#include <map>#include <set>#include <cstring>#include <cstdio>#include <cmath>#define met(a,b) memset(a, b, sizeof(a));#define IN freopen("in.txt", "r", stdin);using namespace std;typedef long long LL;typedef pair<int, int> PII;const int maxn = 1e6 + 100;const int INF = 0x7fffffff;char s[maxn];int nxt[maxn];int main() { #ifdef _LOCAL IN; #endif // _LOCAL while(cin >> s+1) { nxt[0] = 0; int cur = 0, last = 0; int len = strlen(s+1); for(int i = 1; i <= len; ++i) { char c = s[i]; if(c == '[') cur = 0; else if(c == ']') cur = last; else { nxt[i] = nxt[cur]; nxt[cur] = i; if(cur == last) last = i; cur = i; } } for(int i = nxt[0]; i != 0; i = nxt[i]) printf("%c", s[i]); printf("\n"); } return 0;}
UVA - 12657_Boxes in a Line
思路
双向链表的裸题,不过我写这道题的时候感觉蛮坑的
主要是遍历的时候,最好根据元素个数来遍历,不要像单链表那样直接使用i = next[i]来遍历,因为它有一个循环的过程,搞不好会超时。
然后在插入或者删除的时候,最好将会改变的东西先存下来,以防后面改其它的东西的时候它也跟着变了
还有重要的一点,交换的时候两个物品相邻的情况要特判一下,不要想当然。
代码
#include <algorithm>#include <iostream>#include <sstream>#include <utility>#include <string>#include <vector>#include <queue>#include <map>#include <set>#include <cstring>#include <cstdio>#include <cmath>#define met(a,b) memset(a, b, sizeof(a));#define IN freopen("in.txt", "r", stdin);using namespace std;typedef long long LL;typedef pair<int, int> PII;const int maxn = 1e5 + 100;const int INF = 0x7fffffff;int n, m, x, y, opt;int nxt[maxn], pre[maxn];bool isRev;void combine(int i, int j) { if(i == j) return; nxt[i] = j; pre[j] = i;}void init() { for(int i = 0; i <= n; ++i) combine(i, (i+1) % (n+1));}int main() { #ifdef _LOCAL IN; #endif // _LOCAL int kase = 0; while(scanf("%d%d", &n, &m) == 2) { init(); isRev = 0; for(int i = 0; i < m; ++i) { scanf("%d", &opt); if(opt == 4) isRev = !isRev; else { scanf("%d%d", &x, &y); if(opt != 3 && isRev) opt = 3 - opt; int Px = pre[x], Nx = nxt[x]; int Py = pre[y], Ny = nxt[y]; if(opt == 1) { if(x == Py) continue; combine(Px,Nx); combine(Py, x); combine(x, y); } else if(opt == 2) { if(x == Ny) continue; combine(Px, Nx); combine(y, x); combine(x, Ny); } else { if(x == Ny) swap(x, y); Px = pre[x], Nx = nxt[x]; Py = pre[y], Ny = nxt[y]; if(y == Nx) {combine(Px, y); combine(y, x); combine(x, Ny); } else { combine(Px, y); combine(y,Nx); combine(Py, x); combine(x, Ny);} } } } LL ans = 0; int b = 0; for(int i = 1; i <= n; ++i) { b = nxt[b]; if(i%2) ans += b; } if(isRev && n % 2 == 0) ans = (LL)n*(n+1)/2 - ans; printf("Case %d: %lld\n", ++kase, ans); } return 0;}
- 入门经典_Chap06_例题[一]:队列,栈,链表的数组实现
- 入门经典_Chap06_例题[二]:二叉树的指针及数组实现
- 入门经典_Chap06_例题[三]:图的搜索 Floodfill 拓扑排序 欧拉回路
- 入门经典_Chap06_例题[四]:最后四题
- 入门经典_Chap06_习题:搜索 数据结构 欧拉回路
- 经典数据结构之数组实现的队列
- 算法竞赛入门经典例题-优先队列(阿格斯)
- 队列 队列的数组实现及链表实现
- 后缀数组经典例题
- 队列的链表与数组实现
- 队列的数组和链表实现
- 队列(一)——队列的数组实现方式
- C经典例题一
- 【经典优先队列例题整理】
- 栈、队列、背包的数组与链表实现
- 经典数据结构之队列的链表实现方法
- 简单的栈和队列经典实现
- 经典面试题一:用两个栈实现一个队列
- linux下使用opencv接口函数对图像进行光滑处理
- 常用证书操作函数
- maven多模块
- android 绘制自定义控件
- 《深入理解java虚拟机》学习笔记3——垃圾回收算法
- 入门经典_Chap06_例题[一]:队列,栈,链表的数组实现
- KinectV2 qt pcl 实现点云显示
- Cygwin下的NDK环境配置与编译
- 队列和栈的基本性质和应用
- lintcode整数排序|选择排序算法(Java)
- SQL Server Profiler工具使用说明
- tomcat集群--整合Apache服务器,采用mod_JK连接模式
- 自我整理:iOS端APP真机调试和打ipa包完整流程
- 史上最全最好用的自定义交易支付密码及弹框