P1739 表达式括号匹配
用了一个计数器计数,出现异常情况跳出。结果根据计数器判断。
题目描述
假设一个表达式有英文字母(小写)、运算符(+,—,*,/)和左右小(圆)括号构成,以“@”作为表达式的结束符。请编写一个程序检查表达式中的左右圆括号是否匹配,若匹配,则返回“YES”;否则返回“NO”。表达式长度小于255,左圆括号少于20个。
输入格式
一行:表达式
输出格式
一行:“YES” 或“NO”
输入输出样例
输入 #1复制
2*(x+y)/(1-x)@
输出 #1复制
YES
输入 #2复制
(25+x)(a(a+b+b)@
输出 #2复制
NO
#include<iostream>
using namespace std;
int main() {
char expression[300];
cin >> expression;
int flag = 0;
for (int i = 0; expression[i] != '\0'; i++) {
if (expression[i] == '(')flag++;
if (expression[i] == ')')flag--;
if (flag < 0)break;
}
if (flag == 0)cout << "YES";
else cout << "NO";
return 0;
}
P1160 队列安排
本题总结:
1. 链表的使用
这题主要是训练了关于链表的STL的使用,另外还学习了如何使用打表的方法来对链表的读取进行加速。
链表的一些常用的方法在下面进行简要说明:
//建立链表
list<int> l={1};//建立一个1个元素的链表,只含有元素1;
//链表的元素查找
int k;
auto iter = find(l.begin(),l.end(),k);//从链表中查找元素值为k的迭代器,将这个迭代器返回到iter
//链表插入
l.insert(iter,k);//在iter这个迭代器前插入元素k,该函数执行完后返回插入元素的迭代器
//链表迭代器的移动,这一部分可以和插入一起使用
auto n=next(iter);//next方法在<iterator>中,将链表后移一位
auto p=prev(iter);//prev方法也在iterator中,将链表前移一位
auto advan=advance(iter,n);//将链表移动n位,如果n是负数就向前移动
//链表删除
l.erase(iter);//删除iter所指向的元素,删除后链表自动拼接。
//merge
a.merge(ilist b);//将ab链表合并
//拆分链表
list1.splice(iter1,list2);//将链表1从iter1开始分开,将list2插入其中
list2.splice(list2.begin(),iter1,it,list1.end());//向list2中插入
2. 链表查找的优化
由于每次使用find(iter1,iter2,ElementToFind)的时候都是线性查找,时间很慢。因此定义了一个迭代器数组,利用它来进行查找,对于要删除的量,使用了一个bool数组来进行查询。
list<int>::iterator pos[10000];// 迭代器赋值
pos[1]=l.begin();
//插入或者删除的时候只需如下操作
l.insert(pos[i],j);//向第i个元素的对应的迭代器前插入元素j
题目描述
一个学校里老师要将班上N个同学排成一列,同学被编号为1∼N,他采取如下的方法:
先将1号同学安排进队列,这时队列中只有他一个人;
2-N号同学依次入列,编号为i的同学入列方式为:老师指定编号为i的同学站在编号为 1∼(i−1)中某位同学(即之前已经入列的同学)的左边或右边;
从队列中去掉M(M<N)M个同学,其他同学位置顺序不变。
在所有同学按照上述方法队列排列完毕后,老师想知道从左到右所有同学的编号。
输入格式
第1行为一个正整数N,表示了有N个同学。
第2-N行,第i行包含两个整数k,p,其中k为小于i的正整数,p为0或者1。若p为0,则表示将ii号同学插入到k号同学的左边,p为1则表示插入到右边。
第N+1行为一个正整数M,表示去掉的同学数目。
接下来M行,每行一个正整数x,表示将x号同学从队列中移去,如果xx号同学已经不在队列中则忽略这一条指令。
输出格式
1行,包含最多NN个空格隔开的正整数,表示了队列从左到右所有同学的编号,行末换行且无空格。
输入输出样例
输入 #1复制
4
1 0
2 1
1 0
2
3
3
输出 #1复制
2 4 1
说明/提示
样例解释:
将同学22插入至同学11左边,此时队列为:
2 121
将同学33插入至同学22右边,此时队列为:
2 3 1231
将同学44插入至同学11左边,此时队列为:
2 3 4 12341
将同学33从队列中移出,此时队列为:
2 4 1241
同学33已经不在队列中,忽略最后一条指令
最终队列:
2 4 1241
数据范围
对于20%20%的数据,有N≤10N≤10;
对于40%40%的数据,有N≤1000N≤1000;
对于100%100%的数据,有N, M≤100000N,M≤100000。
代码
#include<iostream>
#include<algorithm>
#include<list>
#include<iterator>
using namespace std;
int main() {
int N;
cin >> N;
list<int> l = { 1 };
int k, p;
list<int>::iterator pos[100005];
bool Erase[100005] = {};
pos[1] = l.begin();
for (int i = 2; i <= N; i++) {
cin >> k >> p;
//auto iter = find(l.begin(), l.end(), k);//找到k这个值的迭代器;但是这个线性查找太慢了,我们用一个打表的方法来优化
if (p == 0) {//左边插入
pos[i]=l.insert(pos[k], i);
}
else {//右边插入
//advance(iter, 1);
pos[i]=l.insert(next(pos[k]), i);//next是iterator里面的方法
}
}
int M;
cin >> M;
for (int i = 0; i < M; i++) {
cin >> k;
if (Erase[k] == false) {
l.erase(pos[k]);
Erase[k] = true;
}
}
//for (int i = 0; i < M; i++) {
// cin >> k;
// auto iter=find(l.begin(), l.end(), k);
// if(iter!=l.end())
// l.erase(iter);
//}
for (auto x : l) {
cout << x << " ";
}
return 0;
}