2021CCCC天梯赛L2题解

L2第一题:包装机
大体题意是给筐和轨道的容量,然后经过一系列操作后输出流水线上的物品。轨道的操作就像队列,筐的操作符合栈的特性。理解题之后我们就知道了,这是一道模拟送分题,开始加速操作他把。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>

using namespace std;

const int N = 110, M = 1010;

int n, m, S;
queue<char> q[N];
stack<char> stk;

int main()
{
    scanf("%d%d%d", &n, &m, &S);
    char str[M];
    for (int i = 1; i <= n; i ++ )
    {
        scanf("%s", str);
        for (int j = 0; j < m; j ++ )
            q[i].push(str[j]);
    }

    int x;
    while (scanf("%d", &x), x != -1)
    {
        if (!x)
        {
            if (stk.size())
            {
                printf("%c", stk.top());
                stk.pop();
            }
        }
        else
        {
            if (q[x].size())
            {
                if (stk.size() == S)
                {
                    printf("%c", stk.top());
                    stk.pop();
                }
                stk.push(q[x].front());
                q[x].pop();
            }
        }
    }

    return 0;
}

然后来到第二题病毒溯源
一看题病毒能产生一代二代变异,求最长的链子,这不就是让求树里面最长的一条路径m。一看输入,边也没权值,用二维数组就行,也可以练练邻接表

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
int e[N],ne[N],h[N],idx;
int n;
int son[N];
bool st[N];
void add(int a, int b)  // 添加一条边a->b
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}
int dfs (int t){
    int res = 0;
     son[t] = -1;
    for (int i = h[t];~i;i=ne[i]){
        int x = e[i];
        int y = dfs (x);
        if (y>res) {res = y,son[t]=x;}
        else if (y==res){son[t] = min(son[t],x);}
    }
    return res+1;
}
int main()
{
     memset(h, -1, sizeof h);
    int b,c;
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ){
        scanf("%d", &c);
        for (int j = 0; j < c; j ++ ){
            scanf("%d", &b);
            add(i, b);
            st[b] = true;
        }
    }
    int root = 0;
    while(st[root]) root++;
    printf ("%d\n",dfs(root));
    printf ("%d",root);
    while (son[root]!=-1){
        root = son[root];
        printf (" %d",root);
    }
    return 0;
}

第三题清点代码库,听yxc大佬说这就是STL库的应用,直接上代码把,map、pair、,咱用的也不行。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>

#define x first
#define y second

using namespace std;

const int N = 10010;

int n, m;
map<vector<int>, int> cnt;
vector<pair<int, vector<int>>> ans;

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ )
    {
        vector<int> line;
        for (int j = 0; j < m; j ++ )
        {
            int x;
            scanf("%d", &x);
            line.push_back(x);
        }
        cnt[line] ++ ;
    }

    for (auto& p: cnt) ans.push_back({-p.y, p.x});
    sort(ans.begin(), ans.end());

    printf("%d\n", cnt.size());
    for (auto& p: ans)
    {
        printf("%d", -p.x);
        for (auto x: p.y)
            printf(" %d", x);
        puts("");
    }

    return 0;
}

第四题哲哲打游戏,这个题可是太有意思了,题目好长一大堆,但是题目与我们平常打的单机游戏相似,打一会不想打了,就存档,这样下次玩就能读档接着上次玩,不用再重新开头打了。根据输入,可以看出出来这是一道图的题,然后模拟所有操作,输出存档的剧情点编号,和最终的剧情编号就行了。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

const int N = 100010, M = 110;

int n, m;
vector<int> g[N];   //用邻接表存储
int record[M];

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++ )
    {
        int cnt;
        scanf("%d", &cnt);
        while (cnt -- )
        {
            int x;
            scanf("%d", &x);
            g[i].push_back(x);
        }
    }

    int p = 1;
    while (m -- )
    {
        int a, b;
        scanf("%d%d", &a, &b);
        if (a == 0)
        {
            p = g[p][b - 1];
        }
        else if (a == 1)
        {
            record[b] = p;
            printf("%d\n", p);
        }
        else
        {
            p = record[b];
        }
    }
    printf("%d\n", p);
    return 0;
}```

这几道题就这样弄完了,感觉是不是考了基础的算法,L3的最后一题才是BOSS。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值