浙江大学城市学院2017年ACM实验室新生选拔赛

Brackets

给定一个字符串,由()这三个字符组成。现在你可以将其中的每个变成一个左括号或者一个右括号或者删除。请判断能否形成一个合法的括号序列。

一个括号序列S是合法的,当且仅当它满足下列任一条件:

S为空。
S = (A),其中A为一个合法的括号序列。
S = AB,其中A和B均为合法的括号序列。
例如,() , ()()和((()))()均为合法的括号序列。而)(和())(不是合法的括号序列。

输入
输入的第一行为一个整数T,代表有 T (1 ≤ T ≤ 100) 组数据。接下来有T组测试数据。

每组数据有两行,输入的第一行为n,表示为字符串的长度(1 ≤ n ≤ 10000),第二行为需要判断的字符串,保证该字符串仅由(*)三种字符组成,且长度为n。

输出
对于每组数据输出一行,如果能形成合法的括号序列,输出YES (不含引号,下同),否则输出NO。

样例输入
3
2
()
3
(*)
4
(*))
样例输出
YES
YES
YES

思路:*可以作为左括号,右括号和删除。不需要考虑多余的如何处理 。
先把*当成左括号,从左到右跑一边,如果右括号的数量大于左括号和星号的数量,flag=0,做完的时候去判断2倍星号的数量是不是小于l,如果小于flag=0;
右边也一样的做一遍。

#include<bits/stdc++.h>
using namespace std;
int main ()
{
    int T; cin >> T;
    while (T--){
        string s;
        int len; cin>>len;
        cin >> s;
        int l=0,ss=0;
        int flag=1;
        for(int i=0;i<len;i++){
            if(s[i]=='('||s[i]=='*') {
                l++;
                if(s[i]=='*') ss++;
            }
            else l--;
            if(l<0) flag=0;
        }
      //  printf("flag=%d\n",flag);
      if (ss<l-ss) flag=0;
        int r=0; ss=0;
        for(int i=len-1;i>=0;i--){
            if(s[i]==')'||s[i]=='*'){
                r++;
                if(s[i]=='*') ss++;
            }
            else r--;
            if(r<0) flag=0;
        }
        if(ss<r-ss) flag=0;
        if(flag) puts("YES");
        else puts("NO");
    }
}

DNF Master

It is known to all that OY likes playing the game DNF very much and spends a lot of time on it. The most interesting thing in the game DNF is of course the augmenting system. Recently, the game released the feature Super Augment Mode and OY couldn’t wait to try it.

There are n weapons in OY’s inventory and the i-th weapon has a power of ai. In the Super Augment Mode, OY can choose at most K weapons in his inventory and augment them in the forge. After a successful augmentation, a new weapon with the power equal to the sum of the powers of all the weapons in the forge is created. This new weapon can be used in further augmentations.

It is also known to all that the company that runs the game DNF is very greedy and every time OY creates a new weapon, he needs to pay money in dollars equal to the power of the new weapon in order to get it. And to ensure that the augmentation will succeed with 100% possibility, OY will pay P dollars to get a VIP Augmentation Ticket every time he uses the augmentation forge.

OY wants to become a strong player very much, so he plans to make several augmentations such that in the end he has one single strongest weapon. At the same time, he wants to spend as little money as possible in this process. Please calculate the minimum amount of money he needs to pay for him.

输入
The first line of the input contains a single integer T (1 ≤ T ≤ 1000), the number of test cases. T cases follow.

The first line of each test case contains three integers n,K,P, their meanings are described in the problem statement above.

The second line contains n integers, the i-th integer denotes ai, the power of the i-th weapon. It is guaranteed that: 1 ≤ n ≤ 2000, 2 ≤ K ≤ 10, 0 ≤ P,ai ≤ 10000.

输出
For each test case, output a line containing a single integer, the minimum amount of money in dollars that OY needs to pay.

样例输入
2
3 2 1
1 2 3
3 3 1
1 2 3
样例输出
11
7
题意:给你n个数,一次最多融合k个,每次融合消耗这几个的值加上p。
思路:k叉哈夫曼树。首先每次融合之后新生成的也要在放入里面,所以一定是从小的开始融合。但是要最后合成一把武器。在这之前不一定每次都是k个,这样就会浪费。对于不满足的我们补充(n-1)%(k-1)个0就可以了。

#include<bits/stdc++.h>
using namespace std;
int a[3000];
int main ()
{
    int t; scanf("%d",&t);
    while (t--){
        int flag = 0 ;
        int n,k,p; scanf("%d %d %d",&n,&k,&p);
        priority_queue <int,vector<int>,greater<int>> q;
        for (int i=0;i<n; i++) scanf("%d",&a[i]), q.push(a[i]);
        int ans = 0;
        int kk = k;
        int temp = 0;
        while (1){
            while((n-1)%(k-1)!=0) n++,q.push(0);
            if (flag) break;
            while (kk--){
                ans += q.top();
                temp += q.top();
                q.pop();
                if (q.empty()) {
                    flag = 1;
                    break;
                }
            }
            ans += p;
            q.push(temp);
            temp = 0;
            kk = k;
        }

        printf("%d\n",ans);


    }
}
/*
2
4 3 1
1 2 3 4
*/

Go! Pokemon Master

Although Sono is twenty years old, he still has a child’s heart and wants to become a Pok? emon master.
Fortunately, Sono got his own Pok? emon on his twentieth birthday and is on his way to becoming a
Pok? emon master. Now, Sono has just met his ?rst opponent. As he is still not very skilled in battle, he
asks you to help him determine whether he can win the battle.
Each Pok? emon has eight attributes: HP (hit points), Physical Attack, Physical Defense, Magical Attack,
Magical Defense, Speed, Element Type and Attack Type (which is either Physical or Magical). The rules
of the battle are as follows:
1. The battle is turn-based. In each turn both sides will attack once, the Pok? emon with a higher Speed
attacks ?rst. If the Speed of the two Pok? emons are the same, Sono’s Pok? emon will attack ?rst.
2. If a Pok? emon’s Attack Type is Physical, the Base Damage it will do will be equal to its Physical
Attack minus the opponent’s Physical Defense.
3. If a Pok? emon’s Attack Type is Magical, the Base Damage it will do will be equal to its Magical
Attack minus the opponent’s Magical Defense.
4. As is mentioned above, each Pok? emon has an Element Type, which is either Water, Fire or Grass.
Each Element Type is weak to another: Fire is weak to Water, Grass is weak to Fire and Water is
weak to Grass. Base on the Element Type of the two Pok? emons, the Real Damage is calculated as
follows:
• If the attacking Pok? emon’s Element Type is weak to its opponent’s, then the Real Damage it
will do will be equal to (Base Damage)/2, rounded down.
• If the opponent’s Element Type is weak to the attacking Pok? emon’s, then the Real Damage
will be equal to (Base Damage) ∗ 2.
• If neither of the above two cases is true (which means the two Pok? emons has the same Element
Type), then the Real Damage will be equal to Base Damage.
5. If the Base Damage is less than 1, then Rule 4 does not apply and the Real Damage will be equal
to 1.
6. If after applying Rule 4 the Real Damage is less than 1 then the the Real Damage will be equal to
1.
7. The opponent’s HP will decrease by the Real Damage. If after the attack the opponent’s HP is less
than or equal to 0, the battle ends immediately and the attacking Pok? emon wins.

输入
The first line of the input contains a single integer T (1 ≤ T ≤ 1000), the number of test cases. T test
cases follow.
The first line of each test case contains eight integers, denoting Sono’s Pok? emon’s HP, Physical Attack,
Physical Defense, Magical Attack, Magical Defense, Speed, Element Type and Attack Type respectively.
The second line contains the opponent’s Pok? emon’s attributes in the same format.
The values of HP, Physical Attack, Physical Defense, Magical Attack, Magical Defense and Speed will be
between 1 and 255 inclusive.
Element Type will be equal to either 0,1, or 2, where 0 denotes Water, 1 denotes Fire and 2 denotes
Grass.
Attack Type will be equal to either 0 or 1, where 0 denotes Physical and 1 denotes Magical.

输出
For each test case output in a single line ?WIN? (without quotes) if Sono can win, otherwise output
?LOSE? (without quotes).

样例输入
3
67 241 114 79 210 26 2 0
77 4 10 251 210 218 2 0
231 245 34 88 6 77 1 0
145 151 102 19 206 128 1 0
146 43 184 128 170 127 2 1
85 220 82 200 180 206 2 1
样例输出
WIN
LOSE
LOSE
题意:回合制宠物小精灵战斗。园长的大暴力模拟题(●ˇ∀ˇ●)。
思路:模拟模拟。

#include<bits/stdc++.h>
using namespace std;
int main ()
{
    int T; scanf("%d",&T);
    while (T--){
        int hp,pa,pd,ma,md,speed,et,At;
        scanf("%d%d%d%d%d%d%d%d",&hp,&pa,&pd,&ma,&md,&speed,&et,&At);
        int hp1,pa1,pd1,ma1,md1,speed1,et1,At1;
        scanf("%d%d%d%d%d%d%d%d",&hp1,&pa1,&pd1,&ma1,&md1,&speed1,&et1,&At1);
        int bd,bd1;
        if(At==1) bd=ma-md1; //physical
        else bd=pa-pd1;
        if(At1==1) bd1=ma1-md; //physical
        else bd1=pa1-pd;
        if((et==0&&et1==1) || (et==1&&et1==2) || (et==2&&et1==0))  {
            bd*=2,bd1/=2;
            if(bd1<=1) bd1=1; if(bd<=1) bd=1;
        }
        if((et==0&&et1==2) || (et==1&&et1==0) || (et==2&&et1==1))  {
            bd/=2,bd1*=2;
            if(bd1<=1) bd1=1; if(bd<=1) bd=1;
        }
        if(bd1<=1) bd1=1; if(bd<=1) bd=1;
        while(hp>0&&hp1>0){
            if(speed>=speed1){
                hp1-=bd; if(hp1<=0) break;
                hp-=bd1;if(hp<=0) break;
            }
            else {
                hp-=bd1;if(hp<=0) break;
                hp1-=bd; if(hp1<=0) break;
            }
        }
        if(hp>0) puts("WIN");
        else puts("LOSE");
    }
    return 0;
}

Sherlock

There is a little sister in the laboratory, who is particularly keen on Sherlock and she watches it again and again every year in the summer vacation. As a fan of the great detective, she decides to play a game with her partners. The rules are as follows: There are N persons in total, and each person has a unique ID from 1 to N. Everyone will say, I know the K-th person tells the truth. or I know the K-th person is lying. It is known that only one person is lying and all the others speak the truth. Now you must nd out who is lying.

输入
The rst line of the input contains a single integer T (1 ≤ T ≤ 10), the number of test cases. T test cases follow. The rst line of each case contains a single integer N (3 ≤ N ≤ 100), the number of persons participating in the game. In the following N lines, the i-th line describes what the i-th person said. Each line contains two integers K and F (1 ≤ K ≤ N,0 ≤ F ≤ 1), separated by a single space. If F = 1, the i-th person says I know the K-th person tells the truth. If F = 0, the i-th person says I know the K-th person is lying. It is guaranteed that either F = 1 or K 6= i, which means no person will say that himself is lying. It is also guaranteed that exactly one person is lying.

输出
For each test case, output a line containing a single integer, denoting the ID of the person that is lying.

样例输入
1
3
2 1
2 1
2 0
样例输出
3
题意:小学奥数题啊。只有一个人说谎。找到他。
思路:枚举第i个人说谎,要判断这个人有没有说谎,那么有三种情况能证明这个人没有说谎。
1.有人证明i没说谎(即有人和i说的一样)
2.有人证明别人说慌(因为只有一个人说谎)
3.i说别人说真话,那么他没说谎 。
排除这三种情况就行。

#include<bits/stdc++.h>
using namespace std;
struct Node{
    int x,y;
}node[110];
int main ()
{
    int T; scanf("%d",&T);
    while (T--){
        int ans=0;
        int n; scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d%d",&node[i].x,&node[i].y);
        for(int i=1;i<=n;i++){ //枚举第i个人说谎
            bool flag=0;
            for(int j=1;j<=n;j++){
                 if(i==j){
                    if(node[j].x!=i&&node[j].y){
                        flag=1;
                        break;
                    }
                 }

                 else {
                    if(node[j].x==i&&node[j].y) {
                        flag=1;
                        break;
                    }
                    if(!node[j].y&&node[j].x!=i){
                        flag=1;
                        break;
                    }
                 }
            }
            if(!flag){
                ans=i;
                break;
            }
        }
        printf("%d\n",ans);

    }
    return 0;
}

7 Days

魔冰最近沉迷于手游永远的七日之都,在经历了游戏的两周目之后,她终于把薇拉这个神器使成功喂到了S级。这是一个近战的AOE神器,她的欧皇朋友园长在开局抽出了一个漂亮的妮维小姐姐。但是魔冰一点也不羡慕园长(萝莉控)的远程神器使,为了证明自己的的神器使比园长的强,她向园长提出了PK。

妮维的血很脆,所以要尽量避免被薇拉打中,但是可以远距离进行输出,而薇拉的大招可以在限定范围内把妮维抓回来胖揍,但是距离一远就不能打到。园长和魔冰选择了一张狭窄的地图进行攻击,这个地图只有一条路,路上有一定数量的点,点数为偶数个。魔冰和园长依次选择去掉一个点,直到剩下两个点为止,作为她们初始的战斗距离,魔冰希望两人的战斗距离尽量靠近,这样就能锤爆园长的萝莉,而园长则希望尽量远离近战的控制。

系统图每次生成偶数个点,每个点的位置给出,园长觉得自己一定不会输,就给自己插上了旗,大气地让魔冰先进行移除点。两个人的选择都足够聪明,但是园长很懒,园长想知道两人每次移除到最后,剩下两个点的距离,请帮他计算初始的战斗距离的结果L。

输入
输入的第一行为一个整数T,代表有 T (1 ≤ T ≤ 10) 组数据,接下来有T组数据。

每组数据第一行为一个整数n,代表有 n (1 ≤ n ≤ 1000) 个座位标号,n保证为偶数。

接下来一行有n个整数 xi (0 ≤ xi ≤ 109),表示n个点的坐标。

输出
对于每组数据,在单独一行中输出最后两个标记间的距离L.

样例输入
3
2
0 1
4
31 10 2 7
2
12 34
样例输出
1
8
22
思路:是一道结论题。最后这两个的距离是n/2-1。遍历一边就行找到最小值就行。

#include<bits/stdc++.h>
using namespace std;
int a[10000];
int main ()
{
    int t; scanf("%d",&t);
    while (t--){
        int n; scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        sort(a+1,a+1+n);
        int in=n/2-1;
        int lo=a[in+2]-a[1];
        for(int i=1;i<=in+1;i++) lo=min(lo,a[in+i+1]-a[i]);
        printf("%d\n",lo);
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值