首页 > 编程语言 >2022“杭电杯”中国大学生算法设计超级联赛(3)签到题4题

2022“杭电杯”中国大学生算法设计超级联赛(3)签到题4题

时间:2023-04-27 22:33:13浏览次数:36  
标签:Little 签到 LL contains cin maxn 2022 杭电杯 line


Problems
Solved Problem ID Title Ratio (Accepted / Submitted)
1001 Equipment Upgrade 33.53% (115/343)
1002 Boss Rush 13.79% (246/1784)
1003 Cyber Language 69.82% (1189/1703)
1004 Divide the Sweets 3.24% (7/216)
1005 Spanning Tree Game 9.83% (40/407)
1006 Dusk Moon 6.91% (32/463)
1007 Shallow Moon 4.35% (1/23)
1008 Laser Alarm 12.91% (131/1015)
1009 Package Delivery 11.41% (667/5847)
1010 Range Reachability Query 5.88% (3/51)
1011 Taxi 15.37% (213/1386)
1012 Two Permutations 18.29% (516/2821)

文章目录

  • 3.Cyber Language
  • 9.Package Delivery
  • 12.Two Permutations
  • 2.Boss Rush

3.Cyber Language

Cyber Language
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 203 Accepted Submission(s): 145

Problem Description
You may have ever seen the following words written in cyber language: ‘‘KK’’, ‘‘DDW’’, ‘‘SMWY’’, which means ‘‘kan kan’’, ‘‘dai dai wo’’, ‘‘shen me wan yi’’, respectively.

To translate a Chinese sentence into cyber language, you need to find the first letter of each Chinese character, and write it in upper-case.

You will be given several Chinese sentences, please translate them into the cyber language described above.

Input
The first line contains a single integer T (1≤T≤10), the number of test cases. For each test case:

The only line contains several Chinese characters written in lower-case, separated by exactly one space. It is guaranteed that the length of each line is at least 1 and at most 50.

Output
For each test case, output a single line containing a string, denoting the corresponding word written in the cyber language.

Sample Input
3
kan kan
dai dai wo
shen me wan yi

Sample Output
KK
DDW
SMWY

Source
2022“杭电杯”中国大学生算法设计超级联赛(3)

题意:

思路:

  • 签到模拟,遍历每个字符,如果一个字符的前一个字符是空格或者它是第一个字符,那么把它转大写输出。
#include<bits/stdc++.h>
using namespace std;

int main(){
    int T;  cin>>T;  cin.get();
    string s;
    while(T--){
        getline(cin,s);
        for(int i = 0; i < s.size(); i++){
            if(i==0||s[i-1]==' '){
                cout<<(char)toupper(s[i]);
            }
        }
        cout<<"\n";
    }
    return 0;
}

9.Package Delivery

Package Delivery
Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 946 Accepted Submission(s): 264

Problem Description
Little Q likes online shopping very much. In the next 109 days, there will be n packages delivered to the post office in total. Let’s label the next 109 days as day 1, day 2, …, day 109 respectively. For the i-th package, it will arrive at the post office at day li, and the deadline to take it back home is day ri, which means Little Q can take it back home at day x if and only if li≤x≤ri.

Every time Little Q comes to the post office, he can take at most k packages together back home at the same time. Note that Little Q can go to the post office multiple times during a single day. Please help Little Q determine how to take these n packages back home such that the number of times he will go to the post office is minimized.

Input
The first line contains a single integer T (1≤T≤3000), the number of test cases. For each test case:

The first line contains two integers n and k (1≤k≤n≤100000), denoting the number of packages and the number of packages Little Q can carry at the same time.

Each of the following n lines contains two integers li and ri (1≤li≤ri≤109), describing a package.

It is guaranteed that the sum of all n is at most 1000000.

Output
For each test case, output a single line containing an integer, denoting the minimum possible number of times that Little Q will go to the post office.

Sample Input
1
4 2
1 3
2 4
6 7
4 7

Sample Output
2

Source
2022“杭电杯”中国大学生算法设计超级联赛(3)

题意:

  • 给出n个区间,每次可以去掉小于等于k个存在重叠的区间,求最少多少次去掉所有的区间。

思路:

  • 考虑r最小的那个区间k,第一次取快递放在第rk 天一定不会使结果变差。
  • 此时可能有很多区间覆盖了rk,那么为了尽量延后下一次取快递的日期,此时的最优策略应该是选择覆盖rk且r值最小的k个区间。
  • 使用优先队列找到并去掉这些区间后,递归重复上述过程直至处理完所有n 个区间即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
#define IOS ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)

struct node{ int l, r, id; }a[maxn], b[maxn];
bool cmpl(node x, node y){  return x.l<y.l; }
bool cmpr(node x, node y){  return x.r<y.r; }
int del[maxn];

typedef pair<int,int>P;
priority_queue<P,vector<P>,greater<P> >q; //左键小根堆

int main(){
    IOS;
    int T;  cin>>T;
    while(T--){
        int n, k;  cin>>n>>k;
        for(int i = 1; i <= n; i++){
            cin>>a[i].l>>a[i].r;  a[i].id=i;
            b[i] = a[i];
            del[i] = 0; //初始化
        }
        sort(a+1,a+n+1,cmpr);
        sort(b+1,b+n+1,cmpl);
        int ans = 0, j = 1;
        for(int i = 1; i <= n; i++){
            if(del[a[i].id])continue; //共同标识id,标识这个元素被删了
            while(j<=n && b[j].l<=a[i].r){//覆盖rk的
                q.push(P(b[j].r, b[j].id));  j++;//按r值从小到大排
            }
            ans++; //去掉rk
            for(int t=1; t <= k; t++){//去掉k个或全部
                if(q.empty())break;
                del[q.top().second] = 1;
                q.pop();
            }
        }
        cout<<ans<<"\n";
    }
    return 0;
}

12.Two Permutations

Two Permutations
Time Limit: 4000/4000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1038 Accepted Submission(s): 276

Problem Description
There are two permutations P1,P2,…,Pn, Q1,Q2,…,Qn and a sequence R. Initially, R is empty. While at least one of P and Q is non-empty, you need to choose a non-empty array (P or Q), pop its leftmost element, and attach it to the right end of R. Finally, you will get a sequence R of length 2n.

You will be given a sequence S of length 2n, please count the number of possible ways to merge P and Q into R such that R=S. Two ways are considered different if and only if you choose the element from different arrays in a step.

Input
The first line contains a single integer T (1≤T≤300), the number of test cases. For each test case:

The first line contains a single integer n (1≤n≤300000), denoting the length of each permutation.

The second line contains n distinct integers P1,P2,…,Pn (1≤Pi≤n).

The third line contains n distinct integers Q1,Q2,…,Qn (1≤Qi≤n).

The fourth line contains 2n integers S1,S2,…,S2n (1≤Si≤n).

It is guaranteed that the sum of all n is at most 2000000.

Output
For each test case, output a single line containing an integer, denoting the number of possible ways. Note that the answer may be extremely large, so please print it modulo 998244353 instead.

Sample Input
2
3
1 2 3
1 2 3
1 2 1 3 2 3
2
1 2
1 2
1 2 2 1

Sample Output
2
0

Source
2022“杭电杯”中国大学生算法设计超级联赛(3)

题意:

  • 给出两个长为n的排列P和Q,每次随机从P或Q中选一个数字放入新序列得到长为2n的数组S。
  • 求从PQ得到S的方案数有多少种。

思路:

  • 首先特判序列 S 中每个数字出现次数不都为2的情况,此时答案为0。
  • 因为PQ都是1e5以内的排列,所以不难记录1-n每个数字在PQ中的位置,甚至S也是同理,每个数字只会出现两次。
  • 然后拿P去匹配S,不难想到DP。当P的前i项,Q的前j项匹配上了S时的方案数。但是因为状态n方会爆空间和时间。
  • 考虑用性质去优化。Pi这个数字在S中最多出现2次,因此第二维只需要2个空间就可以记录下来,毕竟这个数字不是在P就肯定在S了,如果不在S那就是0了。
    因此状态 f[i,j] 表示 P 的前 i 项匹配上了S,且Pi 匹配 S 中数字Pi 第 j 次出现的位置时的方案数。
  • 转移时枚举 Pi+1 匹配哪个位置,那么Pi 匹配的位置与Pi+1 匹配的位置中间的那段连续子串需要完全匹配Q 中对应的子串。 可以用字符串Hash进行O(1)的判断。
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)
typedef long long LL;
const LL maxn = 3e5+10, mod = 998244353;
LL a[maxn], b[maxn], c[maxn*2], pc[maxn*2][2];//记录c中每个数第i次出现的位置
LL f[maxn][2], ans, n, n2;//pi与s匹配,pi在s中第j次出现(即q中的pi是否已出现在s中)

//字符串哈希
const LL di = 233;
LL h[maxn*2], fb[maxn*2], fc[maxn*2];
void init(LL ed){ h[0] = 1; for(LL i = 1; i < ed; i++)h[i]=h[i-1]*di; }
LL ask(LL f[], LL l, LL r){ return f[r]-f[l-1]*h[r-l+1]; }
LL check(LL bl, LL br, LL cl, LL cr){//O(1)判断序列q[bl,br]和s[cl,cr]是否相同
    if(bl>br)return 1;
    if(bl<1||br>n || cl<1||cr>n2)return 0;
    return ask(fb,bl,br)==ask(fc,cl,cr);
}

int main(){
    IOS;
    init(maxn*2);
    LL T;  cin>>T;
    while(T--){
        memset(pc,0,sizeof(pc));
        memset(f,0,sizeof(f));
        //input
        cin>>n;
        for(LL i = 1; i <= n; i++)cin>>a[i];
        for(LL i = 1; i <= n; i++)cin>>b[i], fb[i]=fb[i-1]*di+b[i];
        n2 = n*2;
        for(LL i = 1; i <= n2; i++){
            cin>>c[i];  fc[i] = fc[i-1]*di+c[i];
            if(pc[c[i]][0]==0)pc[c[i]][0] = i; else pc[c[i]][1] = i;
        }
        //特判不都为2
        LL ii;  for(ii = 1; ii <= n; ii++)if(!pc[ii][0] || !pc[ii][1])break;
        if(ii<=n){  cout<<"0\n";  continue; }
        //处理其他的
        for(LL j = 0; j < 2; j++){            //p[1]在s中出现1,2次的位置
            LL x = pc[a[1]][j];               //s的[1,x-1]都是q
            if(check(1,x-1,1,x-1))f[1][j] = 1;
        }
        for(LL i = 1; i < n; i++){            //p前i个与s匹配
            for(LL j = 0; j < 2; j++){
                if(f[i][j]){
                    LL x = pc[a[i]][j];       //p[i]在s中的位置
                    for(LL k = 0; k < 2; k++){//枚举p[i]是第几次出现
                        LL y = pc[a[i+1]][k]; //p[i+1]在s中的位置
                        if(y <= x) continue;   //[x+1,y-1]必须为q子串
                        if(check(x-i+1,y-i-1, x+1, y-1)){//p匹配了i个,位置在s的x,所以q就是x-i个
                            f[i+1][k] = (f[i+1][k]+f[i][j]+mod)%mod;
                        }
                    }
                }
            }
        }
        LL ans = 0;
        for(LL j = 0; j < 2; j++){            //p[n]后面的整段都必须在q中
            if(f[n][j]){
                LL x = pc[a[n]][j];
                if(check(x-n+1, n, x+1, n2)){ //x-n即为q当前匹配了的个数,一直到末尾(包含)即可
                    ans = (ans+f[n][j]+mod)%mod;
                }
            }
        }
        cout<<ans<<"\n";
    }
    return 0;
}

2.Boss Rush

Boss Rush
Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1243 Accepted Submission(s): 326

Problem Description
Finally, Little Q gets his weapon at level 105 in the RPG game, now he is trying to beat the boss as soon as possible. The boss has H units of health point (HP), Little Q needs to cause at least H units of damage to beat the boss.

Little Q has learnt n skills, labeled by 1,2,…,n. Each skill can not be used multiple times, because there is not enough time for Little Q to wait for the skill to cool down. Assume Little Q uses the i-th skill at the x-th frame, the actor controlled by him will take ti frames to perform, which means Little Q will not be allowed to use other skills until the (x+ti)-th frame. The length of the damage sequence of the i-th skill is leni, which means the skill will cause di,j (0≤j<leni) units of damage at the (x+j)-th frame if Little Q uses the i-th skill at the x-th frame. Note that leni can be greater than ti, for example, the burning skill can burn the boss for a long period, but takes a little time to cast the fire.

The game starts at the 0-th frame. Your task is to help Little Q beat the boss as soon as possible, or determine Little Q can’t beat the boss using all the skills at most once.

Input
The first line contains a single integer T (1≤T≤100), the number of test cases. For each test case:

The first line contains two integers n and H (1≤n≤18, 1≤H≤1018), denoting the number of skills and the HP of the boss.

For each skill, the first line contains two integers ti and leni (1≤ti,leni≤100000), the second line contains leni integers di,0,di,1,…,di,leni−1 (1≤di,j≤109).

It is guaranteed that the sum of all leni is at most 3000000, and there are at most 5 cases such that n>10.

Output
For each test case, output a single line containing an integer, denoting the first frame to beat the boss. If it is impossible to beat the boss, please print ‘’-1’’ instead.

Sample Input
3
1 100
5 3
50 60 70
2 100
2 3
40 40 100
100 2
20 5
1 1000
1 1
999

Sample Output
1
2
-1

Source
2022“杭电杯”中国大学生算法设计超级联赛(3)

题意:

  • BOSS有H点血。你有n个技能,每个技能只能用一次,且用完后ti秒内不能用其他技能,效果是leni秒内每秒造成d[i,lenj]点伤害。
  • 求最少用多少时间可以干掉boss。

思路:

  • 二分答案,转化为判断 T 秒内能否打败BOSS,即求出 T 秒内能打出的最高伤害,判断是
    否大于等于H。
  • 从前往后依次发动若干个技能,则下一个技能可以发动的时刻等于之前发动过的技能的时间之和,因此只和之前发动过哪些技能有关。因为技能数量很小,因此可以状压枚举,令ss[S]表示发动集合S的所有技能需要花费的时间,可以预处理后O1得到结果
  • 设f(s)表示发动了s集合的技能后在T秒内最多能结算多少伤害 ,枚举不在S中的某个技能x作为下一个技能进行转移,由于技能发动时刻已知,因此可以O(1) 计算出在T秒内下一个技能可以结算多少伤害。
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)
#define IOS ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)
typedef long long LL;
const LL maxn = 2e5+10;

LL n, hp, t[20], len[20], d[20][maxn], ss[(1<<20)+1], f[(1<<20)+1];
LL check(LL T){
    for(LL S=0; S < (1<<n); S++)f[S] = -1;
    f[0] = 0;                        //f[S], 集合S可以打出的最大伤害,由不在S中的进行转移
    for(LL S=0; S < (1<<n); S++){
        if(f[S] >= hp)return 1;      //可以干掉boss
        if(f[S] < 0)continue;        //无法转移到技能S 
        if(ss[S] > T)continue;       //发动S需要的时间已经>T了,再见
        LL cur = ss[S], w = f[S];    //当前用的时间,造成的伤害
        for(LL i = 0; i < n; i++){ 
            if(!(S>>i&1)){           //枚举不在S中的技能进行转移
                if(cur+len[i]-1<=T){ //时间<=T,可以全伤
                    f[S|(1<<i)] = max(f[S|(1<<i)], w+d[i][len[i]-1]);
                }else{               //时间不够,用T-cur的全部时间去打多少算多少
                    f[S|(1<<i)] = max(f[S|(1<<i)], w+d[i][T-cur]); 
                }
            }
        }
    }
    return 0;
}

int main(){
    IOS;
    LL T;  cin>>T;
    while(T--){
        cin>>n>>hp;
        LL sum = 0;
        for(LL i = 0; i < n; i++){
            cin>>t[i]>>len[i];   //等待,伤害
            sum += t[i]+len[i]-1;
            for(LL j = 0; j < len[i]; j++)cin>>d[i][j];
            for(LL j = 1; j < len[i]; j++)d[i][j] += d[i][j-1];
        }
        for(LL S = 1; S < (1<<n); S++){ //ss[S]: 发动集合S需要的前置时间
            ss[S] = ss[S-(S&-S)]+t[__builtin_ctz(S&-S)];//+=末位技能发动需要的时间
        }
        LL l = 0, r = sum, ans = -1;
        while(l <= r){
            LL mid = l+r>>1;
            if(check(mid)){
                ans = mid;
                r = mid-1;
            }else l = mid+1;
        }
        cout<<ans<<"\n";
    }
    return 0;
}


标签:Little,签到,LL,contains,cin,maxn,2022,杭电杯,line
From: https://blog.51cto.com/gwj1314/6232260

相关文章

  • 2022“杭电杯”中国大学生算法设计超级联赛(1)签到题5题
    SolvedPro.IDTitleRatio(Accepted/Submitted)1001String11.88%(125/1052)1002Dragonslayer19.56%(473/2418)1003Backpack14.23%(270/1897)1004Ball15.29%(52/340)1005Grammar12.21%(21/172)1006Travelplan24.18%(22/91)1007Treasure12.93%(38/294)......
  • “蔚来杯“2022牛客暑期多校训练营2,签到题GJK
    题号标题已通过代码通过率团队的状态AFalfawithPolygon点击查看56/445Blight点击查看50/326CLinkwithNimGame点击查看192/1035DLinkwithGameGlitch点击查看831/6211EFalfawithSubstring点击查看264/3287FNIOwithStringGame点击查看52/......
  • “蔚来杯“2022牛客暑期多校训练营1,签到题GADI
    题号标题已通过代码通过率团队的状态AVillages:Landlines点击查看1673/4177通过BSpiritCircleObservation点击查看39/299未通过CGrabtheSeat!点击查看88/392未通过DMochaandRailgun点击查看1589/8517通过ELTCS点击查看43/324未通过FCut点击......
  • 青岛市程序设计竞赛冲刺④(2022山东省小学组补赛试题)
    1.独木桥原题: 解题思路:n个人中,每个人越靠近一个端点,就朝着那个方向走到头,求出最大距离即最大时间AC代码:#include<bits/stdc++.h>#definelllonglongusingnamespacestd;constintN=1e6+5;intn,L,a[N],ans=0;intmain(){ freopen("bridge.in","r",stdin); fr......
  • 2022-04-27:用go语言重写ffmpeg的remuxing.c示例。
    2022-04-27:用go语言重写ffmpeg的remuxing.c示例。答案2022-04-27:ffmpeg的remuxing.c是一个用于将多媒体文件从一种容器格式转换为另一种容器格式的命令行工具。它可以将音频、视频和字幕等元素从源文件中提取出来,并按照用户指定的方式重新封装到目标文件中。在本篇文章中,我将对ffmp......
  • 2022年,软件测试还能学吗?别学了,软件测试岗位饱和了...
    8年前,我懵懂的选择了软件测试这个行业,穷困潦倒的时候,爸妈给我付了2万块钱进入了一家培训机构,我怀着感激和破釜沉舟的情绪开始学习软件测试。3个月的学习时间,住群租宿舍,吃盒饭,平时上课认真听讲,周末就跑自习室。在学了基础课程之后,找工作的时候以比较优秀的成绩通过了各种面试。那......
  • Buildroot(2022.08-rc1)+busybox(1.35.0)启动流程
     关键词:busybox,inittab,syslogd,klogd,mdev,modprobe,watchdog,telnetd等等。 《busybox启动流程简单解析:从init到shelllogin》详细介绍了init对inittab的解析和执行。下面为buildroot(2022.08-rc1)的启动脚本:/etc/inittabsysinit->/bin/mount-tprocproc/proc......
  • SQL Server 2022 AlwaysOn新特性之包含可用性组介绍
    由于技术能力有限,文章仅能进行简要分析和说明,如有不对的地方,请指正,谢谢......
  • "Wed Aug 03 19:48:03 +0800 2022"这种字符串,怎么转成时间格式年月日
    今日鸡汤清瑟怨遥夜,绕弦风雨哀。大家好,我是Python进阶者。一、前言昨天在Python黄金交流群【此类生物】问了一个Python时间处理的问题二、实现过程这里一共有两个方法,实现的过程是类似的。这里【瑜亮老师】给了一个回答,代码如下所示:fromdatetimeimportdatetimed='WedAug03......
  • 2022-04-26:给定一个数组componets,长度为A, componets[i] = j,代表i类型的任务需要耗时j
    2022-04-26:给定一个数组componets,长度为A,componets[i]=j,代表i类型的任务需要耗时j给定一个二维数组orders,长度为M,orders[i][0]代表i号订单下单时间orders[i][1]代表i号订单是哪种类型的任务,毫无疑问orders[i][1]<A一开始所有流水线都在0时刻待命,给定一个正数nums,表示流水......