牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题

Posted 小哈里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题相关的知识,希望对你有一定的参考价值。

题号 标题 已通过代码 通过率 我的状态
A A+B Problem 点击查看 1705/4843 通过, (贪心
B Komorebi的数学课 点击查看 1372/5349 通过 (快速幂
C 次佛锅 点击查看 1070/5160 通过 (字符串STL
D Setsuna的K数列 点击查看 597/2425 通过 (二进制)di
E Wiki下象棋 点击查看 308/2312 通过(BFS最短路
F 黄金律法 点击查看 1286/3529 通过(排序不等式
G 天气预报 点击查看 184/2800 通过(前缀和,尺取法) die
H 叠硬币 点击查看 67/702 通过(背包dp,打印方案)die
I A+B Problem again 点击查看 27/512 通过(数据敏感,字典树)die
J 史东薇尔城 点击查看 461/4005 通过(Dijkstra板子
K 取模 点击查看 207/3545 通过(数论分块板子)die
L 剪绳子 点击查看 84/593 通过(STL集合二分)di
M 数硬币 点击查看 34/385 通过(线段树板子)di
N 截肢葛瑞克 点击查看 0/288 未通过
O 上海施工小学 点击查看 5/1817 未通过

1、A+B Problem

  • 找到最大值和次大值,如果当前数字不是最大值就加最大值,不然就加次大值
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
int a[maxn], f[maxn];
int main()
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n;   cin>>n;
    if(n==1)
        int x;  cin>>x;  cout<<x;
        return 0;
    
    for(int i = 1; i <= n; i++)
        cin>>a[i];  f[i] = a[i];
    
    sort(f+1,f+n+1);
    for(int i = 1; i <= n; i++)
        if(a[i]!=f[n])cout<<a[i]+f[n]<<" ";
        else cout<<a[i]+f[n-1]<<" ";
    
    return 0;



2、Komorebi的数学课

  • 显然是一个快速幂板子题
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
LL pows(LL a, LL x, LL p)if(x==0)return 1; LL t = pows(a, x>>1,p);if(x%2==0)return t*t%p;return t*t%p*a%p;
int main()
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    LL n;  cin>>n;
    cout<<pows(n,n,n+2);
    return 0;

3、次佛锅

  • 判断T次询问的字符串在第一行位置后面的数字。
  • stringsteam加到map里面,直接输出就行
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
int main()
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    string s;  getline(cin,s);
    stringstream ss(s);
    map<string,int>ma;
    int x;
    while(ss>>s>>x)
        ma[s]+=x;
    
    int T;  cin>>T;
    while(T--)
        cin>>s;
        cout<<ma[s]<<"\\n";
    
    return 0;



4、Setsuna的K数列

  • 一开始没想到一直不知道怎么暴力,后来自己想想就是一个进制枚举
  • 考虑3^0,3^1,3^2,3^3,,,3^n各自可以使用0次或1次,那么就是选或者不选的问题
  • 那么就是判断第n个数的二进制位是否是1,如果是1就加上对应的3^i即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn = 1e7+10,mod=1e9+7;
LL pows(LL a, LL x, LL p)if(x==0)return 1; LL t = pows(a, x>>1,p);if(x%2==0)return t*t%p;return t*t%p*a%p;
int a[maxn];
int main()
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    LL n, k;  cin>>n>>k;
    LL w = n, ans = 0, t = 1;
    while(w)
        if(w&1)
            ans = (ans+t)%mod;
        
        t = t*k%mod;
        w >>= 1;
    
    cout<<ans<<"\\n";
    return 0;



5、Wiki下象棋

  • 给出两种走位方式,分别求起点到终点的最短路
  • 直接bfs暴力即可
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL pows(LL a, LL x, LL p)if(x==0)return 1; LL t = pows(a, x>>1,p);if(x%2==0)return t*t%p;return t*t%p*a%p;
int a[310][310];

struct nodeint x, y,st=0;;
int vis[310][310];
int n, m;
int k, sx,sy, ex, ey;
int dx[] = -2,-2,2,2,-1,1,-1,1;
int dy[] = 1,-1,1,-1,-2,-2,2,2;
int bfs(int ok)
    memset(vis,0,sizeof(vis));
    queue<node>q;
    q.push(sx,sy,0);
    while(q.size())
        node t = q.front();  q.pop();
        if(t.x==ex&&t.y==ey)
            return t.st;
        
        for(int i = 0; i < 8; i++)
            int nx = t.x+dx[i], ny = t.y+dy[i];
            if(nx<1||nx>n||ny<1||ny>m)continue;
            if(a[nx][ny])continue;
            if(vis[nx][ny])continue;
            if(ok==1)
                if(abs(dx[i])==2)
                    if(a[t.x+dx[i]/2][t.y]==1)///||a[t.x+dx[i]][t.y]==1
                        continue;
                    
                else
                    if(a[t.x][t.y+dy[i]/2]==1)//||a[t.x][t.y+dy[i]]==1
                        continue;
                    
                
            
            q.push(nx,ny,t.st+1);
            vis[nx][ny] = 1;
        
    
    return -1;


int main()
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T;  cin>>T;
    while(T--)
        cin>>n>>m;
        cin>>k>>sx>>sy>>ex>>ey;
        memset(a,0,sizeof(a));
        for(int i = 1; i <= k; i++)
            int tx, ty;  cin>>tx>>ty;
            a[tx][ty] = 1;
        
        cout<<bfs(0)<<" "<<bfs(1)<<"\\n";
    
    return 0;



6、黄金律法

  • 给出两个长度相同的序列,分别重新排序后,令每个对应位置上的数两两相乘加起来的值最小,求结果,ai<1e5。
  • 贪心,排序不等式结论,一个从大到小一个从小到大即可,注意不开ll只有10分
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e7+10;
LL a[maxn], b[maxn];
bool cmp(LL x, LL y)
    return x>y;

int main()
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int T;  cin>>T;
    while(T--)
        int n;  cin>>n;
        for(int i = 1; i <= n; i++)cin>>a[i];
        for(int i = 1; i <= n; i++)cin>>b[i];
        sort(a+1,a+n+1);
        sort(b+1,b+n+1,cmp);
        LL sum = 0;
        for(int i = 1; i <= n; i++)
            sum += a[i]*b[i];
        
        cout<<sum<<"\\n";
    
    return 0;



7、天气预报

  • 将01串存为数组,即判断一个区间的区间和>=b,且长度>=a+b时满足条件,求区间个数。
  • 想到了前缀和O1求区间和,但是不知道为啥前缀和写错了(bushi),然后按照双指针每次枚举终点,k从前往后直到刚好不能满足条件为止(尺取法),那么以i为终点的区间个数就是k-1个,即包含区间[k,i]并向前面可以拓展k-1个。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
LL c[maxn], s[maxn], sb[maxn];
int main()
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n;  cin>>n;
    LL a, b;  cin>>a>>b;
    string str;  cin>>str; 
    LL ans = 0, k = 1;
    for(int i = 1; i <= n; i++)
        // c[i] = str[i-1]-'0'; //93%WA
        // s[i] = s[i-1]+c[i]; //在家
        // sb[i] = i-s[i];     //出门
        if(str[i-1]=='0')s[i]=s[i-1], sb[i]=sb[i-1]+1;
        else s[i]=s[i-1]+1, sb[i]=sb[i-1];
        while(sb[i]-sb[k-1]>=a && s[i]-s[k-1]>=b && k<=i)k++;
        ans += k-1;
    
    if(a==0 && b==0)ans++;
    cout<<ans<<"\\n";
    return 0;



8、叠硬币

  • n堆硬币,选择最少的数量叠起来刚好等于高度H,多种方案选字典序小的输出。
  • dfs暴力所有选择方案+剪枝剪掉大于H高度的子树,33分
  • 首先不难想到要堆数量尽可能小,那么先从大到小排个序。
  • 然后考虑每堆硬币选还是不选,最后高度为h,就是类似于01背包问题变种+打印方案。
    记f[i]表示拼成高度为i的硬币堆需要的最小长度,转移时尝试使用当前a[i]为所有h到a[i]的最小高度更新,取max(f[j-a[i]]+1,f[i]),初始值都为正无穷,f[0]=0。
  • 记p[j]=i表示高度为j时使用的点为i,循环打印即可
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 3030;
int a[maxn], f[maxn], p[maxn];
int main()
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n, h;  cin>>n>>h;
    for(int i = 1; i <= n; i++)cin>>a[i];
    sort(a+1,a+n+1,[](int x, int y)return x>y;);
    memset(f,0x3f,sizeof(f));
    f[0] = 0;
    for(int i = 1; i <= n; i++)
        for(int j = h; j >= a[i]; j--)
            if(f[j-a[i]]==f[h+1])continue;
            if(f[j]>=f[j-a[i]]+1以上是关于牛客 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛 签到题13题的主要内容,如果未能解决你的问题,请参考以下文章

又一重量级国字头赛事!中国大学生计算机设计大赛全面启动

2022中国高校计算机大赛 微信大数据挑战赛Top 1-6 方案总结

2019年GPLT L2-4 彩虹瓶 比赛题解 中国高校计算机大赛-团体程序设计天梯赛题解

2019年GPLT L2-3 深入虎穴 比赛题解 中国高校计算机大赛-团体程序设计天梯赛题解

2019年GPLT L2-1 特立独行的幸福 比赛题解 中国高校计算机大赛-团体程序设计天梯赛题解

2018年SAS中国高校数据分析大赛圆满落幕 同济大学夺冠