2018CCPC女生赛重现 | 总结+部分题解

本文是2018年CCPC女子组比赛的总结,包括赛题分析和部分解题思路。文章详细介绍了几个赛题的解题方法,涉及字符串处理、评测系统设计、后缀数组等方面。对于每道题目,提供了最短验题人和参赛队伍代码长度的统计,并给出了样例输入输出。解题思路中强调了正确理解题意和注意边界条件的重要性。

因为有很多队已经克隆过了

所以在VJ上可以看到其他队伍的排名情况和交题记录

刚开始几分钟 就有队伍过了F题

果断看F题 确实是个水题

HDU6292  赛题分析

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)
Total Submission(s): 1882    Accepted Submission(s): 869

 

Problem Description

著名出题人小Q每次比赛后都会写一份《赛题分析》,包含比赛概况、每题的参考算法以及一些统计数值。

对于一道题来说,小Q会统计最短的验题人代码长度(Shortest judge solution)以及赛内参赛队伍最短的AC代码长度(Shortest team solution)。

统计验题人代码长度比较容易,因为验题人最多也不会超过20个。但是统计选手代码长度就不容易了,因为大赛区动辄三四百支队伍。

请写一个程序,帮助小Q统计最短代码长度。

 

Input

第一行包含一个正整数T(1≤T≤13),表示赛题数量。

每道题第一行包含两个整数n,m(2≤n≤20,0≤m≤500),分别表示验题人数量以及AC了该题的队伍数量。

第二行包含n个正整数a1,a2,...,an(50≤ai≤65536),依次表示每个验题人的代码字节数。

第三行包含m个正整数b1,b2,...,bn(50≤bi≤65536),依次表示每支AC队伍的代码字节数。若m=0则该行为空行。

 

Output

对于第i(1≤i≤T)道题,输出三行,第一行输出Problem x:,其中x=i+1000。

第二行输出Shortest judge solution: y bytes.,其中y表示最短的验题人代码字节数。

第三行输出Shortest team solution: z bytes.,其中z表示最短的选手代码字节数,若不存在请输出N/A。

注意:间隔都是一个空格。

 

Sample Input

2 
3 2 
3627 1460 
5288 2365 2671 
2 0 
5510 7682

Sample Output

Problem 1001:

Shortest judge solution: 1460 bytes.

Shortest team solution: 2365 bytes.

Problem 1002:

Shortest judge solution: 5510 bytes.

Shortest team solution: N/A bytes.

 思路:

暴力寻找最小值即可

注意判断 m 输入为 0 时 不输出最小值 而是 N/A

(我因为少了一个句号没发现 而WA了好多发 还好队友大白也写了一遍就AC了) 

代码

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
int main()
{
    int t, n, m, x, y;
    scanf("%d", &t);
    for (int i = 1; i <= t; i++) {
        scanf("%d%d", &n, &m);
        printf("Problem %d:\n", 1000 + i);
        scanf("%d", &x);
        int minn = x;
        for (int j = 1; j < n; j++) {
            scanf("%d", &x);
            minn = min(minn, x);
        }
        printf("Shortest judge solution: %d bytes.\n", minn);
        if (m > 0) {
            scanf("%d", &y);
            int  mi = y;
            for (int k = 1; k < m; k++) {
                scanf("%d", &y);
                mi = min(mi, y);
            }
            printf("Shortest team solution: %d bytes.\n", mi);
        } else {
            printf("Shortest team solution: N/A bytes.\n");
        }
    }
    return 0;
}

PS: 这里不用long long ,数据不算很大……

 

与此同时 Alone 看了K题

2021年CCPC女生程序设计竞部分题解如下: - **A公交路线题解**: ```cpp #include <bits/stdc++.h> using namespace std; int main() { int n, x, y, arr[15]={0}; cin >> n >> x >> y; for (int i = 1; i <= n; i++) { cin >> arr[i]; } int m, xx, brr[15]={0}; cin >> m; if(x<y){ for(int i=1;i<=m;i++){ cin>>brr[i]; if(brr[i]!=arr[i+x]){ cout<<"Wrong"<<endl; return 0; } } if(x-1<1||x-m<1){ cout<<"Right"<<endl; return 0; } for(int i=1;i<=m;i++){ if(arr[x-i]!=brr[i]){ cout<<"Right"<<endl; return 0; } } cout<<"Unsure"<<endl; return 0; }else{ for(int i=1;i<=m;i++){ cin>>brr[i]; if(brr[i]!=arr[x-i]){ cout<<"Wrong"<<endl; return 0; } } if(x==n||x+m>n){ cout<<"Right"<<endl; return 0; } for(int i=1;i<=m;i++){ if(arr[x+i]!=brr[i]){ cout<<"Wrong"<<endl; return 0; } } cout<<"Unsure"<<endl; } return 0; } ``` - **C题解**: 思路是寻找一个最短的 `t`,使得 `t` 不是 `s(l,r)` 的子序列,假设现在位于 `x`,下一步有 `m` 个选择,要使子序列尽可能小,就选择离 `x` 最远的那个字母,直到走出 `r` 为止。问转化为从 `l` 开始沿着 `_next` 一路往右跳,要跳多少步才能跳到 `> r` 的地方,使用倍增的方法使得 `_next[i][j]` 是 `i` 从 `2^j` 步到达的最远位置。 ```cpp #include<bits/stdc++.h> using namespace std; char s[200100]; int _next[200100][26];//st表 int v[2000100]; int a[26]; int main(){ int m,n; scanf("%d%d",&m,&n); scanf("%s",s+1); for(int i=0;i<=25;i++){ a[i]=n+1; } for(int i=n;i>=0;i--){ for(int j=0;j<m;j++){ v[i]=max(v[i],a[j]); } _next[i][0]=v[i]; if(i)a[s[i]-'a']=i; } for(int j = 1; j < 20; j ++){ for(int i = 0; i <= n; i ++) { int t = _next[i][j - 1]; if(t <= n) _next[i][j] = _next[t][j - 1]; else _next[i][j] = n + 1; } } int q; scanf("%d",&q); while(q--){ int l,r; scanf("%d%d",&l,&r); int ans = 0, now = l - 1; for(int j = 19; ~j; j --) if(_next[now][j] <= r) ans += (1 << j), now = _next[now][j]; printf("%d\n",ans+1); } return 0; } ``` 以上代码分别对应2021年CCPC女生程序设计竞A和C题解 [^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值