2021 CCCC天梯赛补题

前言不想看请直接跳过~~~~
前言+检讨:天梯赛我拉垮了,我拖了队伍后腿,我有罪。
分析原因,首先是前一个星期训练量不够,没有跟上队友训练的进度,一些基础的STL的用法使用的也不熟练。
第二,没有把STL用熟,或者是没有真正会用导致比赛时思路有些混乱,打断了思路的连贯性。
第三,把过多时间精力消耗在Debug上,消磨了自己的心态和时间,比如L1-8这道题其实双指针就可以轻松解决的,我非耍小聪明整STL装逼,结果最后调不出来还得再用双指针,分也没拿全,我有罪,拖了全队的后腿。
第四,L2的dfs用的不熟,没有将算法熟练于心像Hello World那些轻松敲出来,反映出近期学习不踏实,有些知识点看似掌握了写了题解,其实换个壳子还是不会。
第五,客观的因素比如电脑死机啥的我就不谈了,就是我水平不够罢了。
今后继续努力!!!


L1前几题太水了,从小干货开始


L1-078 吉老师的回归 (15 分)

在这里插入图片描述

输入样例 1:

5 1
L1-1 is a qiandao problem.
L1-2 is so...easy.
L1-3 is Easy.
L1-4 is qianDao.
Wow, such L1-5, so easy.

输出样例 1:

L1-4 is qianDao.

输入样例 2:

5 4
L1-1 is a-qiandao problem.
L1-2 is so easy.
L1-3 is Easy.
L1-4 is qianDao.
Wow, such L1-5, so!!easy.

输出样例 2:

Wo AK le

思想

这道题恶心在哪呢?其实就是输入的时候如果用了scanf注意前面加getchar就完事了。
想法的话这道题很简单,就是在遍历的时候标记哪些题目是跳过的,如果跳不过的题则消耗一次m,如果某次循环m为0,而且此时做的题目无法跳过,那么就直接输出这道题。如果循环结束后m还大于或等于0(可能最后一次简单题消耗掉了),那么就输出Wo AK le。

AC代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pre(i,a,b) for(int i=a;i>=b;--i)
#define m(x) memset(x,0,sizeof x)
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define PI acos(-1)
typedef long long ll;
const int INF =  0x3f3f3f3f;
const int mod = 1e9+7;
const int maxn = 1e5+10;
string str1 = "qiandao";
string str2 = "easy";
string ans;
int main()
{
    int n,m;
    int flag = 0;
    cin >> n >> m;
    getchar();
    rep(i, 1, n)
    {
        string str;
        getline(cin,str);
        
        int f = false;
        //cout << str << endl;
        //这里调用STL函数库,是简单题则f=true
        string::size_type idx;
        idx = str.find(str1);
        if(idx!=string::npos)f = true;
        idx = str.find(str2);
        if(idx!=string::npos)f = true;
        //注意判断条件有两条,一个是m==0,第二个是不是简单题
        if(m==0&&f==false){flag = 1;ans = str;}//就是标记为输出非AK情况
        if(!f)m--;
        
    }
    if(flag)cout << ans << endl;
    else cout << "Wo AK le" << endl;
    return 0;
}


L1-079 天梯赛的善良 (20 分)

在这里插入图片描述
输入样例:

10
86 75 233 888 666 75 886 888 75 666

输出样例:

75 3
888 2

思想

这道题水的,暴力完事,只需拿个桶记录最大最小,以及其个数就完事了,每次更新,一次便利即可

AC代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pre(i,a,b) for(int i=a;i>=b;--i)
#define m(x) memset(x,0,sizeof x)
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define PI acos(-1)
typedef long long ll;
const int INF =  0x3f3f3f3f;
const int mod = 1e9+7;
const int maxn = 1e6+10;
int a[maxn];
int main()
{
    int n,x;
    int maxx,minn;
    maxx = -1;
    minn = INF;
    cin >> n;
    rep(i,1,n)
    {
        scanf("%d",&x);
        if(!a[x])
        {
            maxx = max(maxx,x);
            minn = min(minn,x);
        }
        a[x] ++;
    }
    printf("%d %d\n",minn,a[minn]);
    printf("%d %d\n",maxx,a[maxx]);   
    return 0;
}

L1-080 乘法口诀数列 (20 分)

这道题说实话当时只拿了17分,有点失望····不知道哪个点卡了(主要切慢了···)

在这里插入图片描述
输入样例:

2 3 10

输出样例:

2 3 6 1 8 6 8 4 8 4

思想

这道题怎么说呢,说恶心其实还好吧,主要是题意要看清,之前题意没搞懂直接莽就很浪费时间····题意就是先给你两个初始数a1,a2,之后的数据通过这两个初始数计算而来,也就是a3为a1*a2,但是如果a3是多位数就得把每一位按权值高到低依次存放入a数组。具体例子看看Sample就懂了。
所以我们用双指针标记,一个是当前已经算好的新数存进stack倒一下(LIFO的原则,具体可以查看我的二进制水题那有写---->传送门)然后存入a数组,另一个指针标记当前是把哪两个数相乘,便于接下来向后移动。


Half-AC代码(两个点没过)

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pre(i,a,b) for(int i=a;i>=b;--i)
#define m(x) memset(x,0,sizeof x)
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define PI acos(-1)
typedef long long ll;
const int INF =  0x3f3f3f3f;
const int mod = 1e9+7;
const int maxn = 1e5+10;
int a[maxn];
int weishu(int k)
{
    int num = 0;
    while(k){k/=10;num++;}
    return num;
}
int main()
{
    int x,y,n;
    scanf("%d%d%d",&x,&y,&n);
    int index1,index2;
    //初始化指针
    index1 = 1;
    index2 = 3;
    a[1] = x;a[2] = y;
    if(x==0||y==0)goto out;
    while(index2<=n)
    {
        int temp = a[index1]*a[index1+1];
        //如果位数就只有一位,那么直接存入此时的index2位置,同时index2向后一位
        if(weishu(temp)==1){a[index2++] = temp;}
        else{
            //因为算出来的多位数是要从权值高到低存放a的
            stack<int>s;
            while(temp)
            {
                s.push(temp%10);
                temp/=10;
            }
            //然后再依次放入a树诅
            while(!s.empty())
            {
            a[index2++] = s.top();
            s.pop();
                //如果下一位需要存放的位置已经超出了需要输出的位数,则及时止损
                if(index2>n)break;
            }
        }
        index1++;
    }
    //输出
    out:
    rep(i, 1, n)
    {
        if(i!=n)printf("%d ",a[i]);
        else printf("%d\n",a[i]);
    }
    return 0;
}

这道题有俩个点没过,就挺奇怪的,特判也加了·······在这里插入图片描述


AC代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pre(i,a,b) for(int i=a;i>=b;--i)
#define m(x) memset(x,0,sizeof x)
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define PI acos(-1)
typedef long long ll;
const int INF =  0x3f3f3f3f;
const int mod = 1e9+7;
const int maxn = 1e5+10;
int a[maxn];
int weishu(int k)
{
    int num = 0;
    while(k){k/=10;num++;}
    return num;
}
int main()
{
    int x,y,n;
    scanf("%d%d%d",&x,&y,&n);
    int index1,index2;
    //初始化指针
    index1 = 3;
    index2 = 3;
    a[1] = x;a[2] = y;
    if(x==0||y==0)goto out;
    do
    {
        int temp = a[index1-1]*a[index1-2];
        //如果位数就只有一位,那么直接存入此时的index2位置,同时index2向后一位
        if(temp<10){a[index2++] = temp;}
        else{
            a[index2++] = temp /10;
            a[index2++] = temp %10;
        }
        index1++;
    }while(index2<=n);
    //输出
    out:
    cout << a[1];
       for (int i = 2; i <= n; i++) {
           cout << " " << a[i];
       }
    cout << endl;
    return 0;
}


见鬼了,改了几个无关紧要的点,反而能过····无语,毒瘤测试点一生黑


L2-037 包装机 (25 分)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

输入样例:

3 4 4
GPLT
PATA
OMSA
3 2 3 0 1 2 0 2 2 0 -1

输出样例:

MATA

思想

这道题就硬模拟呗~~~用STL吧

借用朋友的代码了~~~
https://blog.csdn.net/qq_52480906/article/details/116116174


AC代码

#include<bits/stdc++.h>
using namespace std;
queue<char> q[150];
stack<char> k;
int main() {
    int n, m, smax;
    cin >> n >> m >> smax;
    char x;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> x;
            q[i].push(x);
        }
    }//读入队列
    int op;
    while (cin >> op) {
        if (op == 0&&!k.empty()) {//操作符为0
            cout << k.top();
            k.pop();
        }
        else if (op != -1) {//操作符为推出物品
            if (q[op].empty()) {//框空就不执行
                continue;
            }
            char t;
            t = q[op].front();
            q[op].pop();
            if (k.size() >= smax) {//框满就特判
                cout << k.top();
                k.pop();
                k.push(t);
            }
            else {
                k.push(t);
            }
        }
        else if (op == -1) {//操作符为结束
            break;
        }
    }
    cout << endl;
    return 0;
}

L2-038 病毒溯源 (25 分)

在这里插入图片描述在这里插入图片描述

输入样例:

10
3 6 4 8
0
0
0
2 5 9
0
1 7
1 2
0
2 3 1

输出样例:

4
0 4 9 1

AC代码

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pre(i,a,b) for(int i=a;i>=b;--i)
#define m(x) memset(x,0,sizeof x)
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define PI acos(-1)
#define pb push_back
typedef long long ll;
const int INF =  0x3f3f3f3f;
const int mod = 1e9+7;
const int maxn = 1e5+10;
vector<int> mp[maxn],ans,temp;
int vis[maxn];
int maxx = -1;
void dfs(int u, int k)
{
    if (k > maxx)//如果路径长度比现有长度更长
    {
        maxx = k;//更新最大长度
        ans = temp;//更新最大长度的序列
    }
    for (int i = 0; i < mp[u].size(); i++)
    {
        temp.push_back(mp[u][i]);//模拟每一步
        dfs(mp[u][i], k + 1);
        temp.pop_back();//不要忘记pop出来
    }
    return;
}
int main()
{
    
    m(vis);
    int n;
    cin >> n;
    rep(i,0,n-1)
    {
        int T;
        cin >> T;
        while(T--)
        {
            int x;
            cin >> x;
            mp[i].pb(x);
            vis[x] = 1;
        }
        sort(mp[i].begin(), mp[i].end());
    }
    
//    rep(i, 0, n-1)
//    {
//        for(int j=0;j<mp[i].size();j++)
//        cout << mp[i][j] << " ";
//        cout << endl;
//    }
    
    int std = 0;
    rep(i, 0, n-1)
    if(vis[i]==0){std = i;break;}
    dfs(std,0);
    cout << maxx+1 << endl;
    printf("%d",std);
    rep(i, 0, ans.size()-1)
    {
        printf(" %d",ans[i]);
    }
    cout << endl;
    return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值