线性数据结构
3-1 寄包柜
题目链接
解题思路
思路:
如果开一般数组,int [105] [105] 显然会MLE
,又由已知超市里共计不会超过10^7个寄包格子
,想到用动态数组vector
。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
vector<vector<int> >a;
int n,q;
int main(){
cin>>n>>q;
a.resize(n);
for (int i=1; i<=q; i++){
int k;
scanf("%d",&k);
if (k==1){
int l1,r1,m;
scanf("%d%d%d",&l1,&r1,&m);
if (a[l1].size()<r1+1)
a[l1].resize(r1+1);
a[l1][r1]=m;
}
if (k==2){
int l1,r1;
scanf("%d%d",&l1,&r1);
printf("%d\n",a[l1][r1]);
}
}
system("pause");
return 0;
}
注意: 如果使用resize()
并且 vector
数组从1开始,则修改数组大小时候,范围需要+1
,否则会喜提 20pts
。
3-2 括号序列
题目链接
解题思路
前言:
此题的题目描述和样例都很感人,建议难度直接黑题吧
如果始终没有AC
并且不知道错在了哪里,可以测试一下以下数据:
输入:])[(
输出:[]()[]()
输入:()[)]
输出:()[()]
思路:
可以构造两个栈,sta.c
存放还未匹配的左括号,pt
存放将要输出的序列。top
为sta
中指针,l
为pt
中指针。sta
为结构体,其中sta.num
存放该左括号在pt
中的位置。最后输出的时候,如果sta[j].num
与当前pt
中的i
相等,表示这是一个未匹配的左括号,需要多输出一个匹配的右括号。
#include<bits/stdc++.h>
using namespace std;
struct node{
int num;
char c;
}sta[105];
int main(){
string s;
char pt[205];
getline(cin,s);
int top=0,l=0; //top表示栈中指针 l为输出列表中指针
for (int i=0; i<s.size(); i++){
if (s[i]=='('){
sta[++top].c=s[i];
pt[++l]=s[i];
sta[top].num=l;
}
if (s[i]=='['){
sta[++top].c=s[i];
pt[++l]=s[i];
sta[top].num=l;
}
if (s[i]==')'){
if (sta[top].c=='('){
top--;
pt[++l]=s[i];
}
else {
pt[++l]='(';
pt[++l]=')';
}
}
if (s[i]==']'){
if (sta[top].c=='['){
top--;
pt[++l]=s[i];
}
else {
pt[++l]='[';
pt[++l]=']';
}
}
}
if (top){
for (int i=1,j=1; i<=l; i++)
if (sta[j].num==i){
if (pt[i]=='(')
cout<<"()";
else if (pt[i]=='[')
cout<<"[]";
if (j<top)
j++;
}
else
cout<<pt[i];
}
else
for (int i=1; i<=l; i++)
cout<<pt[i];
system("pause");
return 0;
}
彩蛋:
题面要求的括号匹配很丑陋,笔者觉得这种括号匹配更优美一点:
输入:([()
输出:([()])
输入:])[(
输出:[]()[()]
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
char sta[105],pt[205];
getline(cin,s);
int top=0,l=0; //top表示栈中指针 l为输出列表中指针
for (int i=0; i<s.size(); i++){
if (s[i]=='('){
sta[++top]=s[i];
pt[++l]=s[i];
}
if (s[i]=='['){
sta[++top]=s[i];
pt[++l]=s[i];
}
if (s[i]==')'){
if (sta[top]=='('){
top--;
pt[++l]=s[i];
}
else {
pt[++l]='(';
pt[++l]=')';
}
}
if (s[i]==']'){
if (sta[top]=='['){
top--;
pt[++l]=s[i];
}
else {
pt[++l]='[';
pt[++l]=']';
}
}
}
while (top>0){
if (sta[top]=='('){
pt[++l]=')';
}
if (sta[top]=='['){
pt[++l]=']';
}
top--;
}
for (int i=1; i<=l; i++)
cout<<pt[i];
system("pause");
return 0;
}
尽管这么写连样例都不对,但还是喜提了。60pts
3-3 后缀表达式
题目链接
解题思路
很标准的栈结构。sta
中存放每一个有效数字,并且要注意多位数的处理方式。每一次的运算都在top
与top-1
之间。
#include<bits/stdc++.h>
using namespace std;
int sta[105];
int main(){
int top=0;
char c;
int k;
while (cin>>c&&c!='@'){
int num=0;
if (c>='0'&&c<='9'){
num=c-'0';
while(cin>>c&&c>='0'&&c<='9'){
num=num*10+c-'0';
}
sta[++top]=num;
}
if (c=='+'){
sta[top-1]=sta[top]+sta[top-1];
top--;
}
else if (c=='-'){
sta[top-1]=sta[top-1]-sta[top];
top--;
}
else if (c=='*'){
sta[top-1]=sta[top-1]*sta[top];
top--;
}
else if (c=='/'){
sta[top-1]=sta[top-1]/sta[top];
top--;
}
}
cout<<sta[1];
system("pause");
return 0;
}
3-4 队列安排
题目链接
解题思路
标准的双向链表。构造一个始终位于队首的假元素,以此为起点,不断链接下去,直到一个元素的右边L
为0时。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
struct stu{
int l,r;
bool b=0;
}a[maxn];
int main(){
int n;
cin>>n;
a[0].l=0;
a[0].r=1;
a[0].b=1;
for (int i=2; i<=n; i++){
int num,k;
scanf("%d%d",&num,&k);
if (k==1){
a[i].r=a[num].r;
a[i].l=num;
a[a[num].r].l=i;
a[num].r=i;
}
else {
a[i].r=num;
a[i].l=a[num].l;
a[a[num].l].r=i;
a[num].l=i;
}
}
int m;
cin>>m;
for (int i=1; i<=m; i++){
int k;
scanf("%d",&k);
a[k].b=1;
a[a[k].l].r=a[k].r;
a[a[k].r].l=a[k].l;
}
int i;
for (i=a[0].r; i; i=a[i].r){ //i为0即为末尾的结束
if (!a[i].b)
cout<<i<<" ";
}
system("pause");
return 0;
}