T1表达式括号匹配:
题目描述
假设一个表达式有英文字母(小写)、运算符(+,—,*,/)和左右小(圆)括号构成,以“@”作为表达式的结束符。请编写一个程序检查表达式中的左右圆括号是否匹配,若匹配,则返回“YES”;否则返回“NO”。表达式长度小于255,左圆括号少于20个。
输入输出格式
输入格式:
一行:表达式
输出格式:
一行:“YES” 或“NO”
输入输出样例
输入样例#1: 复制
2*(x+y)/(1-x)@
输出样例#1: 复制
YES
输入样例#2: 复制
(25+x)*(a*(a+b+b)@
输出样例#2: 复制
NO
说明
表达式长度小于255,左圆括号少于20个
#include<bits/stdc++.h>
using namespace std;
char c[5005];
int num;
int main(){
cin>>c;
for(int i=0;c[i]!='@';i++){
if(c[i]=='(')
num++;
else if(c[i]==')')
num--;
if(num<0){
cout<<"NO";
return 0;
}
}
if(num!=0)
cout<<"NO";
else
cout<<"YES";
return 0;
}
T2杂务:
题目描述
John的农场在给奶牛挤奶前有很多杂务要完成,每一项杂务都需要一定的时间来完成它。比如:他们要将奶牛集合起来,将他们赶进牛棚,为奶牛清洗乳房以及一些其它工作。尽早将所有杂务完成是必要的,因为这样才有更多时间挤出更多的牛奶。当然,有些杂务必须在另一些杂务完成的情况下才能进行。比如:只有将奶牛赶进牛棚才能开始为它清洗乳房,还有在未给奶牛清洗乳房之前不能挤奶。我们把这些工作称为完成本项工作的准备工作。至少有一项杂务不要求有准备工作,这个可以最早着手完成的工作,标记为杂务11。John有需要完成的nn个杂务的清单,并且这份清单是有一定顺序的,杂务k(k>1)k(k>1)的准备工作只可能在杂务11至k-1k−1中。
写一个程序从11到nn读入每个杂务的工作说明。计算出所有杂务都被完成的最短时间。当然互相没有关系的杂务可以同时工作,并且,你可以假定John的农场有足够多的工人来同时完成任意多项任务。
输入输出格式
输入格式:
第1行:一个整数nn,必须完成的杂务的数目(3 \le n \le 10,0003≤n≤10,000);
第22至(n+1)(n+1)行: 共有nn行,每行有一些用11个空格隔开的整数,分别表示:
* 工作序号(11至nn,在输入文件中是有序的);
* 完成工作所需要的时间len(1 \le len \le 100)len(1≤len≤100);
* 一些必须完成的准备工作,总数不超过100100个,由一个数字00结束。有些杂务没有需要准备的工作只描述一个单独的00,整个输入文件中不会出现多余的空格。
输出格式:
一个整数,表示完成所有杂务所需的最短时间。
输入输出样例
输入样例#1: 复制
7
1 5 0
2 2 1 0
3 3 2 0
4 6 1 0
5 1 2 4 0
6 8 2 4 0
7 4 3 5 6 0
输出样例#1: 复制
23
#include<bits/stdc++.h>
using namespace std;
int n,k,x,dp[10005],t,ans;
inline int read(){
int k=0,f=1;
char c=getchar();
for(;!isdigit(c);c=getchar())
if(c=='-')
f=-1;
for(;isdigit(c);c=getchar())
k=k*10+c-'0';
return k*f;
}
int main(){
n=read();
while(n--){
x=read();
t=0;
dp[x]=read();
k=read();
while(k!=0){
t=max(t,dp[k]);
k=read();
}
dp[x]+=t;
ans=max(dp[x],ans);
}
cout<<ans;
return 0;
}
T3车站分级:
题目描述
一条单向的铁路线上,依次有编号为 1, 2, …, n1,2,…,n的 nn个火车站。每个火车站都有一个级别,最低为 11 级。现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站 xx,则始发站、终点站之间所有级别大于等于火车站xx 的都必须停靠。(注意:起始站和终点站自然也算作事先已知需要停靠的站点)
例如,下表是55趟车次的运行情况。其中,前44 趟车次均满足要求,而第 55 趟车次由于停靠了 33 号火车站(22 级)却未停靠途经的 66 号火车站(亦为 22 级)而不满足要求。
现有 mm 趟车次的运行情况(全部满足要求),试推算这nn 个火车站至少分为几个不同的级别。
输入输出格式
输入格式:
第一行包含 22 个正整数 n, mn,m,用一个空格隔开。
第 i + 1i+1 行(1 ≤ i ≤ m)(1≤i≤m)中,首先是一个正整数 s_i(2 ≤ s_i ≤ n)si(2≤si≤n),表示第ii 趟车次有 s_isi 个停靠站;接下来有s_isi个正整数,表示所有停靠站的编号,从小到大排列。每两个数之间用一个空格隔开。输入保证所有的车次都满足要求。
输出格式:
一个正整数,即 nn 个火车站最少划分的级别数。
输入输出样例
输入样例#1: 复制
9 2
4 1 3 5 6
3 3 5 6
输出样例#1: 复制
2
输入样例#2: 复制
9 3
4 1 3 5 6
3 3 5 6
3 1 5 9
输出样例#2: 复制
3
说明
对于20\%20%的数据,1 ≤ n, m ≤ 101≤n,m≤10;
对于 50\%50%的数据,1 ≤ n, m ≤ 1001≤n,m≤100;
对于 100\%100%的数据,1 ≤ n, m ≤ 10001≤n,m≤1000。
#include<bits/stdc++.h>
using namespace std;
const int N=1002;
int n,m,i,j,a[N],d[N],ans,f[N],k,vi[N][N],c[N][N],l;
int dfs(int x){
if (f[x]) return f[x];
for (int i=1;i<=c[x][0];i++) f[x]=max(f[x],dfs(c[x][i]));
return ++f[x];
}
int main(){
scanf("%d%d",&n,&m);
for (i=1;i<=m;i++){
scanf("%d",&a[0]);
for (j=1;j<=a[0];j++) scanf("%d",&a[j]);
l=1;
for (j=a[1];j<a[a[0]];j++)
if (a[l]==j) l++;
else for (k=1;k<=a[0];k++)
if (!vi[a[k]][j]) c[a[k]][++c[a[k]][0]]=j,vi[a[k]][j]=1;
}
for (i=1;i<=n;i++) ans=max(ans,dfs(i));
printf("%d",ans);
}
T4树的重量:
题目描述
树可以用来表示物种之间的进化关系。一棵“进化树”是一个带边权的树,其叶节点表示一个物种,两个叶节点之间的距离表示两个物种的差异。现在,一个重要的问题是,根据物种之间的距离,重构相应的“进化树”。
令N={1..n},用一个N上的矩阵M来定义树T。其中,矩阵M满足:对于任意的i,j,k,有M[i,j] + M[j,k] >= M[i,k]。树T满足:
1.叶节点属于集合N;
2.边权均为非负整数;
3.dT(i,j)=M[i,j],其中dT(i,j)表示树上i到j的最短路径长度。
如下图,矩阵M描述了一棵树。
树的重量是指树上所有边权之和。对于任意给出的合法矩阵M,它所能表示树的重量是惟一确定的,不可能找到两棵不同重量的树,它们都符合矩阵M。你的任务就是,根据给出的矩阵M,计算M所表示树的重量。下图是上面给出的矩阵M所能表示的一棵树,这棵树的总重量为15。
输入输出格式
输入格式:
输入数据包含若干组数据。每组数据的第一行是一个整数n(2<n<30)。其后n-1行,给出的是矩阵M的一个上三角(不包含对角线),矩阵中所有元素是不超过100的非负整数。输入数据保证合法。
输入数据以n=0结尾。
输出格式:
对于每组输入,输出一行,一个整数,表示树的重量。
输入输出样例
输入样例#1: 复制
5
5 9 12 8
8 11 7
5 1
4
4
15 36 60
31 55
36
0
输出样例#1: 复制
15
71
#include<bits/stdc++.h>
using namespace std;
int n,dis[35][35];
int main()
{
while(~scanf("%d",&n))
{
if(!n) break;
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
scanf("%d",&dis[i][j]);
int ans=dis[1][2];
for(int i=3;i<=n;i++)
{
int tmp=0x7fffffff;
for(int j=2;j<i;j++)
tmp=min(tmp,(dis[1][i]-dis[1][j]+dis[j][i])/2);
ans+=tmp;
}
printf("%d\n",ans);
}
return 0;
}