week3

本文介绍了三道C++编程题,分别涉及使用map实现寄包柜功能,修复括号序列以及计算后缀表达式。作者强调了map在处理二维数据时的便利性,以及栈在解决后缀表达式问题中的高效性。在括号序列问题中,通过匹配和补全括号来修复序列。
摘要由CSDN通过智能技术生成

第一题

P3613 【深基15.例2】寄包柜

看完题目就十分自信的开了个二维数组,然后就太大超了。之后目光投向map,最开始以为map只有一维的,就把key写成了string,记录的是柜子的地址#格子的地址比如第一个柜子第一个格子就是insert{(1#1,12)};。后来发现map能开二维,那就好写了

写的时候还发现map能直接map1[1][1]=12这样加元素,不用insert,这可比vector好用多了,而且vector的二维和结构体的情况我感觉几乎用不了,感觉vector只能用一维的。

#include <bits/stdc++.h>
using namespace std;
int main() {
	int n, q;
	map<int, map<int, int> >map1;
	cin >> n >> q;
	while (q--) {
		static int temp,i,j,temp1;
		cin >> temp;
		if (temp == 1) {
			cin >> i >> j >> temp1;
			map1[i][j] = temp1;
		}
		else {
			cin >> i >> j;
			cout << map1[i][j]<<endl;
		}
	}
}

第二题

P1241 括号序列

思路是先匹配,在补全,匹配上的括号标记一下。写的时候忽略了匹配不上的括号也要满足没被匹配过的要求,然后卡半天,无语。

#include <bits/stdc++.h>
using namespace std;
struct kuo
{
	int l, r;
	int p = 0;
	string name;
}; kuo ori[400];
void add(int i, int j, int r) {
	//r==1,j加到i右边
	if (r == 1) {
		ori[j].r = ori[i].r;
		ori[j].l = i;
		ori[ori[i].r].l = j;
		ori[i].r = j;
	}
	else {
		ori[j].r = i;
		ori[j].l = ori[i].l;
		ori[ori[i].l].r = j;
		ori[i].l = j;
	}
}

int main() {

	ori[0].r = 0;
	ori[0].l = 0;
	string temp;
	cin >> temp;
	int l = temp.length();
	for (int i = 0; i < l; i++) {
		ori[i + 1].name = temp[i];
		add(i, i + 1, 1);
	}

	for (int i = ori[0].r; i; i = ori[i].r) {
		if (ori[i].name == "]") {
			//j扫右边有无括号
			for (int j = ori[i].l; j; j = ori[j].l) {
				if (ori[j].name == "[") {
					if (ori[j].p == 0) {
						ori[j].p = 1;
						ori[i].p = 1;
						break;
					}
				}
				else if (ori[j].name == "(" && ori[j].p == 0) {
					break;
				}
			}
		}
		else if (ori[i].name == ")") {
			for (int j = ori[i].l; j; j = ori[j].l) {
				if (ori[j].name == "(") {
					if (ori[j].p == 0) {
						ori[j].p = 1;
						ori[i].p = 1;
						break;
					}
				}
				else if (ori[j].name == "["&&ori[j].p==0) {
					break;
				}
			}

		}
	}
	//配对完了
	l++;
	for (int i = ori[0].r; i; i = ori[i].r) {
		if (ori[i].p == 0) {
			l++;
			if (ori[i].name == "[") {
				ori[l].name = "]";
				ori[l].p = 1;
				add(i, l, 1);
			}
			else if (ori[i].name == "(") {
				ori[l].name = ")";
				ori[l].p = 1;
				add(i, l, 1);
			}
			else if (ori[i].name == "]") {
				ori[l].name = "[";
				ori[l].p = 1;
				add(i, l, 0);
			}
			else if (ori[i].name == ")") {
				ori[l].name = "(";
				ori[l].p = 1;
				add(i, l, 0);
			}
		}
	}
	for (int i = ori[0].r; i; i = ori[i].r) {
		cout << ori[i].name;
	}
}

第三题

P1449 后缀表达式
栈真好用,感觉就是个训练栈的题。

#include<bits/stdc++.h>
using namespace std;
int main() {
	char temp;
	int sum=0,a=0,b,c;
	stack<int> ori;
	while (1)
	{
		temp = getchar();
		if (temp == '@') {
			break;
		}
		if (temp == '+') {
			c = ori.top();
			ori.pop();
			b = ori.top();
			ori.pop();
			ori.push(b + c);
		}else if (temp == '-') {
			c = ori.top();
			ori.pop();
			b = ori.top();
			ori.pop();
			ori.push(b - c);
		}else if (temp == '*') {
			c = ori.top();
			ori.pop();
			b = ori.top();
			ori.pop();
			ori.push(b * c);
		}else if (temp == '/') {
			c = ori.top();
			ori.pop();
			b = ori.top();
			ori.pop();
			ori.push(b / c);
		}else if (temp == '.') {
			ori.push(a);
			a = 0;
		}
		else {
			a = a * 10 + temp - '0';
		}
	}
	cout << ori.top();
}

#第四题
P1160 队列安排

第一次写给stu多加了个name属性,之后搜name,有就删,然后毫无疑问的超时了,链表搜索确实,慢。之后拿链表的地址当名字,就过了。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+100;
struct stu
{
	int l,r;
	int d=0;
}; stu ori[maxn];
void add(int i, int j,int r) {
	//右是1,左是0
	if (r == 1) {
		ori[j].l = i;
		ori[j].r = ori[i].r;
		ori[ori[i].r].l = j;
		ori[i].r = j;
	}
	else {
		ori[j].r = i;
		ori[j].l = ori[i].l;
		ori[ori[i].l].r = j;
		ori[i].l = j;
	}
}
int main() {
	int n ;
	int m;
	ori[0].l = 0;
	ori[0].r = 0;
	add(0, 1, 1);
	cin >> n;
	int a, b;
	for (int i = 2; i <= n ; i++) {
		cin >> a >> b;
		add(a, i, b);
	}
	cin >> m;
	int dp[maxn]={0};
	for (int i = 0; i < m; i++) {
		cin >> a;
		if (dp[a] == 0) {
			ori[a].d = 1;
		}
		dp[a] = 1;
	}
	for (int i = ori[0].r; i; i = ori[i].r) {
		if (ori[i].d == 0) {
			cout << i << " ";
		}
	}
	cout << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值