1 选座位 (90 分)
已知公交车中有n排座位,每排都有2个座位。第i排的两个座位的宽度均为wi厘米。没有相同宽度的两排座位。
公共汽车最初是空的。有2n位乘客按顺序先后进入公共汽车。 乘客分为两种类型:
内向者:总是选择两个座位都没人的一排。在这些排中,他选择座位宽度最小的,并占据了其中的一个座位; 外向型:总是选择有人的一排。 在这些排中,他选择座位宽度最大的那个,并占据了空位。
你会得到每排座位的宽度和乘客进入公共汽车的顺序。 请你帮忙确定每位乘客将乘坐哪一排座位。
输入格式:
第一行包含一个整数n(1 ≤ n ≤ 200),表示公共汽车上座位的总排数。
第二行是一个包含n个整数的序列w 1,w 2,...,w n(1 ≤ w i ≤ 10000),其中wi是第i行中每个座位的宽度。 保证所有 w i 都不同。
第三行包含一个长度为 2n 的字符串,由数字“0”和“1”组成,该字符串描述了乘客进入公共汽车的顺序。 如果第j个字符是 '0',那么说明第 j 个进入公共汽车的乘客是内向型的;如果第j个字符是 '1',则表示第j个进入公交车的乘客是外向型的。 保证外向者的数量等于内向者的数量(即'0'和'1'的个数均为 n),并且对于每个外向者总是有合适的行。
输出格式:
打印 2n 个整数,整数之间以空格分隔,表示乘客将坐的排。 乘客的顺序应与输入的顺序相同。
输入样例1:
2
3 1
0011
输出样例1:
2 1 1 2
输入样例2:
6
10 8 9 11 13 5
010010011101
输出样例2:
6 6 2 3 3 1 4 4 1 2 5 5
#include<bits/stdc++.h>
using namespace std;
int n;
typedef struct x_ads
{
int row,width,rest;//有三个变量分别是 排和宽度和剩余座位数
}seat;
void str_sort(seat * a) //定义一个根据结构体里面的 某一个排序的函数
{
seat temp;
for(int i=0;i<n-1;i++)
{
for(int j=0;j<n-1-i;j++)
{
if(a[j].width>a[j+1].width)
{
temp = a[j+1];
a[j+1] = a[j];
a[j] = temp;
}
}
}
}
int main()
{
string s;
cin>>n;
seat arr[n];
for(int i=0;i<n;i++)
{
arr[i].rest = 2;
arr[i].row = i+1;
}
for(int i=0;i<n;i++)
cin>>arr[i].width;
str_sort(arr);
cin>>s;
for(int i=0;i<n*2;i++)
{
if(s[i]=='0')
{
for(int j=0;j<n;j++)
{
if(arr[j].rest==2)
{
cout<<arr[j].row<<" ";
arr[j].rest --;
break;
}
}
}
if(s[i]=='1')
{
for(int j=n-1;j>=0;j--)
{
if(arr[j].rest == 1)
{
cout<<arr[j].row<<" ";
arr[j].rest --;
break;
}
}
}
}
}
2 括号匹配检测 (100 分)
给出一串包含 ( 、 ) 、[ 和 ] 的字符串,字符串在以下三种情况下为合法的:
1)字符串为空;
2)如果A和B都是合法的,那么AB也是合法的;
3)如果A是合法的,那么(A)和[A]也是合法的。
试判断输入的字符串是否合法。
输入格式:
输入包括一串由若干个 ( 、 ) 、 [ 或 ] 组成的字符串,字符串长度不超过100。
输出格式:
如果该字符串合法,输出“Yes”;否则输出“No”。
输入样例:
([])
输出样例:
Yes
#include<bits/stdc++.h>
using namespace std;
stack<char>q;
int main() {
char a[101];
cin >> a;
int i = 0;
for ( i = 0; i < strlen(a); i++) {
if (a[i] == '(' || a[i] == '[')
q.push(a[i]);
if (a[i] == ')') {
if (q.empty()) {
cout << "No";
return 0;
}
else {
if (q.top() == '(')
q.pop();
else {
cout << "No";
return 0;
}
}
}
if (a[i] == ']') {
if (q.empty()) {
cout << "No";
return 0;
}
else {
if (q.top() == '[')
q.pop();
else {
cout << "No";
return 0;
}
}
}
}
cout << "Yes";
return 0;
}
3 括号匹配调整 (100 分)
如果通过插入“ +”和“ 1”可以从中得到格式正确的数学表达式,则将带括号的序列称为正确的。
例如,序列 "(())()","()"和 "(()(()))"是正确的,而")(","(()))("和"(()" 不是。
定义重新排序操作:选择括号序列的任意连续子段(子字符串),然后以任意方式对其中的所有字符进行重新排序。
当重新排序的子段的长度为t时,重新排序操作需要耗时t秒。
例如,对于“))((”,他可以选择子字符串“)(”并重新排序“)()(”(此操作将花费2秒)。
不难看出,重新排序操作不会改变左括号和右括号的数量。
现在,LD想花费最少的时间,通过任意次数(可能为零)执行重新排序操作来使括号序列变成正确的。
输入格式:
第一行包含一个整数n(1≤n≤1e6),表示序列的长度;
第二行包含一个长度为n的字符串,仅由字符‘(’和‘)’组成。
输出格式:
输出一个整数,表示使括号序列正确的最小秒数;如果不可能实现,则输出-1。
输入样例:
8
))((())(
输出样例:
6
#include<bits/stdc++.h>
using namespace std;
stack<char>s;
int main()
{
int n,i,count=0;
cin>>n;
char a[1000001];
cin>>a;
for(i=0;i<n;i++)
{
if(s.empty())
{
if(a[i]=='(')
{
s.push(a[i]);
}
else
{
s.push(a[i]);
count ++;
}
}
else
{
if(a[i]=='(')
{
if(s.top()==')')
{
count ++;
s.pop();
}
else
{
s.push(a[i]);
}
}
if(a[i]==')')
{
if(s.top()=='(')
{
s.pop();
}
else
{
s.push(a[i]);
count ++;
}
}
}
}
if(!s.empty())
{cout<<-1;return 0;}
else
cout<<count;
}
4 奇怪的电梯 (100 分)
c大楼有一个一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第 i 层楼 (1≤i≤N) 上有一个数字Ki(0≤Ki≤N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3,3,1,2,5 代表了Ki (K1=3,K2=3,…),在1楼,按“上”可以到4楼,按“下”是不起作用的,因为没有−2楼。那么,从A楼到B楼至少要按几次按钮呢?
输入格式:
第一行包含3个用空格隔开的正整数,分别表示N,A,B (1≤N≤200,1≤A,B≤N) 。 第二行包含N 个用空格隔开的非负整数,表示Ki 。
输出格式:
输出共一行,即最少按键次数,若无法到达,则输出 −1 。
输入样例:
5 1 5
3 3 1 2 5
输出样例:
3
#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;
int n,a,b;
const int N = 201;
int res = 1e9;
int st[N];
bool stb[N];
void dfs(int now,int step)
{
if(now==b)
{
res = min(res,step);
return;
}
for(int i=0;i<2;i++)//有几种选择循环几次
{
int next = now + st[now]*pow(-1,i);//每次循环的走向
if(stb[next]==true) return;//访问过,就跳过该循环
if(next<=n && next>=1)//进入下一个递归当中
{
stb[next]=true;
dfs(next,step+1);
stb[next]=false;//
}
}
}
int main()
{
cin >> n >> a >> b;
for(int i = 1; i <= n; i ++ )
cin >> st[i];
dfs(a, 0);
if(res == 1e9) cout << -1 << endl;
else cout << res << endl;
return 0;
}
5 168 (100 分)
汉堡包在大街上大摇大摆的走着,看着手机上一道难倒数万人的小学数学题:
1 + 1 = 0
1 + 6 = 1
6 + 6 = 2
8 + 1 = 2
8 + 6 = 3
汉堡包看完之后发现上面这些加法的答案就是看1,6,8中圈圈的个数嘛!
突然之间,所有大厦上的LED屏幕上的广告全部变成数字1,6,8三个数字的随机闪现。
现给你一块n*m的LED屏幕,上面有且仅有一个数字(1,6,or 8),请你输出你看见的那个字母。
输入格式:
第一行输入两个整数n,m(2<= m, n <= 1000);
接下来n行,每行由m个数字0和1组成,其中1表示数字1,6,8的组成部分。
输出格式:
输出一个整数,代表图形表示的数字。
输入样例:
7 7
0 0 0 0 0 0 0
0 0 1 1 1 0 0
0 0 1 0 1 0 0
0 0 1 1 1 0 0
0 0 1 0 1 0 0
0 0 1 1 1 0 0
0 0 0 0 0 0 0
输出样例:
8
#include<stdio.h>
int main()
{
int a[1001][1001];
int b[1001],c[1001];
int n,m,count = 0;
scanf("%d%d",&n,&m);
int i,j,r=0,min;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%d",&a[i][j]);
}
}
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(a[i][j]==1)
b[i] ++;
}
}
for(i=0,j=0;i<n;i++)
{
if(b[i]!=0)
c[j++] = b[i];
}
min = c[j-1];
for(i=j-2;i>=0;i--)
{
if(c[i]<min)
{
min = c[i] ;
count ++ ;
}
}
if(count==0)
printf("1");
if(count==1)
printf("8");
if(count==2)
printf("6");
}
6 寻宝 (100 分)
奕哥今天玩到一款寻宝游戏,地图是一个n*m的矩阵,其中分布着一些宝藏,每个宝藏具有一定的价值,奕哥只能拿走其中一个宝藏。奕哥起始在a行b列。奕哥可以向相邻的一格移动,但不能走出地图外。奕哥初始体力值X,移动一格需要消耗体力值为1。体力耗尽后奕哥无法继续移动。地图中有一些障碍物,奕哥无法移动到障碍物上。奕哥想知道他能拿到的最具价值的宝藏是哪一个。
输入格式:
第一行包含5个整数n,m,a,b,X。n,m分别表示地图行数,列数;a,b表示奕哥起始位置在a行b列;X表示奕哥的体力。
( 1<=n,m<=1000, 1<=a<=n, 1<=b<=m, 0<=X<=1e10)
接下来n行,每行m个整数。第i行第j个整数为Aij (-1<=Aij<=1e9)。若Aij=-1,则表示第i行第j列有障碍物;否则表示该位置有一个价值为Aij的宝物。保证起始位置没有障碍物。
输出格式:
奕哥能拿到价值最高的宝藏的价值。
输入样例:
3 3 1 1 3
0 -1 10
3 5 7
-1 8 15
输出样例:
8
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
int dx[] = {1,0,-1,0};
int dy[] = {0,1,0,-1};
int n,m,a,b;
int Max = 0;
bool st[N][N];
int map[N][N];
void dfs(int x,int y,int step)
{
st[x][y]=true;
if(step==0)
return;
for(int i=0;i<4;i++)
{
int a = x + dx[i];
int b = y + dy[i];
if(a<1||b<1||a>n||b>m)
continue;
if(st[a][b])
continue;
if(map[a][b]==-1)
continue;
Max = max(Max,map[a][b]);
dfs(a,b,step-1);
}
}
int main()
{
int total;
cin >> n >> m >> a >> b >> total;
int i,j;
for(i = 1; i <= n; i ++ )
for( j = 1; j <= m; j ++ )
cin >> map[i][j];
dfs(a,b,total);
cout<<Max<<endl;
}