20190721

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的农场在给奶牛挤奶前有很多杂务要完成,每一项杂务都需要一定的时间来完成它。比如:他们要将奶牛集合起来,将他们赶进牛棚,为奶牛清洗乳房以及一些其它工作。尽早将所有杂务完成是必要的,因为这样才有更多时间挤出更多的牛奶。当然,有些杂务必须在另一些杂务完成的情况下才能进行。比如:只有将奶牛赶进牛棚才能开始为它清洗乳房,还有在未给奶牛清洗乳房之前不能挤奶。我们把这些工作称为完成本项工作的准备工作。至少有一项杂务不要求有准备工作,这个可以最早着手完成的工作,标记为杂务11John有需要完成的nn个杂务的清单,并且这份清单是有一定顺序的,杂务k(k>1)k(k>1)的准备工作只可能在杂务11k-1k−1中。

写一个程序从11nn读入每个杂务的工作说明。计算出所有杂务都被完成的最短时间。当然互相没有关系的杂务可以同时工作,并且,你可以假定John的农场有足够多的工人来同时完成任意多项任务。

输入输出格式

输入格式:
 

第1行:一个整数nn,必须完成的杂务的数目(3 \le n \le 10,0003≤n≤10,000)

22(n+1)(n+1)行: 共有nn行,每行有一些用11个空格隔开的整数,分别表示:

* 工作序号(11nn,在输入文件中是有序的);

* 完成工作所需要的时间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 级)而不满足要求。

https://cdn.luogu.org/upload/pic/1238.png

现有 mm 趟车次的运行情况(全部满足要求),试推算这nn 个火车站至少分为几个不同的级别。

输入输出格式

输入格式:
 

第一行包含 22 个正整数 n, mn,m,用一个空格隔开。

第 i + 1i+1 (1 ≤ i ≤ m)(1≤im)中,首先是一个正整数 s_i(2 ≤ s_i ≤ n)si(2≤sin),表示第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描述了一棵树。

https://cdn.luogu.org/upload/pic/82.png

树的重量是指树上所有边权之和。对于任意给出的合法矩阵M,它所能表示树的重量是惟一确定的,不可能找到两棵不同重量的树,它们都符合矩阵M。你的任务就是,根据给出的矩阵M,计算M所表示树的重量。下图是上面给出的矩阵M所能表示的一棵树,这棵树的总重量为15。

https://cdn.luogu.org/upload/pic/83.png

输入输出格式

输入格式:
 

输入数据包含若干组数据。每组数据的第一行是一个整数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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值