河南萌新联赛第五场

补题4道

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

Alice 和 Bob 在玩一个游戏,他们先从 2000.1.1 到 2024.8.1 这个日期之间(不包括2024.8.1)随意抽取一个日期出来。然后他们轮流对这个日期进行操作:

  1. 把日期的天数加 1,例如:2000.1.1 变到 2000.1.2

  2. 把月份加 1,例如:2000.1.1 变到 2000.2.1

其中如果天数超过应有天数则日期变更到下个月的第 1 天。月份超过 12 则变到下一年的1月。而且进行操作2的时候,如果有这样的日期:2000.1.31,则变成了 2000.2.31,这样的操作是非法的,我们不允许这样做。

所有的操作均要考虑历法和闰年的规定。

谁先将日期变到 2024.8.1 谁就赢了。如果超越了指定日期不算获胜。

每次游戏都是 Alice 先操作,问他有没有必胜策略?

输入描述:

 

第一行一个整数 T,为数据组数(1<=T<=1000)。

接下来一行 X,Y,Z 表示 X 年 Y 月 Z 日。

输出描述:

输出 YES 或者 NO 表示 Alice 是否有必胜策略。

示例1

输入

复制3 2001 11 3 2001 11 2 2001 10 3

3
2001 11 3
2001 11 2
2001 10 3

输出

复制YES NO NO

YES
NO
NO

#include <iostream>
#include <cstdio>
using namespace std;
int t,x,y,z;
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d",&x,&y,&z);
        if((y==9 && z==30) || (y==11 && z==30) || (y+z)%2==0)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

小美想:整个暑假不能全部用来锻炼,也应该收集一些回忆。

整个暑假的回忆将被小美分为两部分:好回忆和坏回忆。

但是并不是所有回忆都可以相安无事的,所以小美也不会随意划分这些回忆的种类。

一个回忆可能会跟其它的一些回忆产生“冲突”,这个“冲突”有一个值 c ,而小美会用波动值来描述整个暑假的美好程度。

只要会产生冲突的两个回忆同时被划分到好回忆或者坏回忆中,小美的波动值就可能发生变化。

具体来说,小美的波动值取决于在最后的划分结果中,同一回忆(好回忆或者坏回忆)种类下最大的那个冲突值。

小美想要自己的暑假尽可能的美好,所以她想请你帮她来划分回忆,使得最后的波动值最小。

输入描述:

 

输出描述:

输出一个整数,表示最小的波动值 。

示例1

输入

复制4 6 2 3 8 1 3 6 2 3 1 4 3 2 1 2 4 1 4 10

4 6
2 3 8
1 3 6
2 3 1
4 3 2
1 2 4
1 4 10

输出

复制4 

4

#include <bits/stdc++.h>

using namespace std;
//think again
const int N = 200010;

int p[N];

int find(int x) {
    return x == p[x] ? x : p[x] = find(p[x]);
}

int main() {
    cin.tie(0)->sync_with_stdio(false);
    int n, m;
    cin >> n >> m;
    vector<tuple<int, int, int>> v(m);
    for (auto& [a, b, c] : v) {
        cin >> a >> b >> c;
    }
    int l = 0, r = 1e6;
    auto check = [&](int mid) {
        iota(p, p + n + n + 1, 0);
        for (auto [a, b, c] : v) {
            if (c > mid) {
                int pa = find(a), pb = find(b);
                if (pa == pb) return false;
                p[find(a + n)] = find(b);
                p[find(b + n)] = find(a);
            }
        }
        return true;
    };
    while (l < r) {
        int mid = l + r >> 1;
        if (check(mid)) {
            r = mid;
        } else {
            l = mid + 1;
        }
    }
    cout << l << '\n';
    return 0;
}

 

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

Bob 有 n 个数,他想知道任意一个区间内的最大值是多少。

输入描述:

 

第一行一个整数 n,表示数的个数,其中 n<=10^6;

第二行为 n 个整数。

第三行一个整数 q,表示询问的次数,其中 q<=10^6;

接下来 q 行,每行有一对 L,R,即询问区间 [L,R] 的最大值。

输出描述:

q 行,每一次询问的结果。

示例1

输入

复制5 10 4 6 2 9 3 1 3 2 4 3 5

5
10 4 6 2 9
3
1 3
2 4
3 5

输出

复制10 6 9

10
6
9

备注:

注意此题输入量极大,需要使用输入优化。

 

#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN = 1000010;
int n, q;
int a[MAXN], lg[MAXN], f[MAXN][20];

// 快速输入
inline int quickRead() {
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

int main() {
    // 输入优化
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    n = quickRead();
    for (int i = 1; i <= n; i++) {
        a[i] = quickRead();
        f[i][0] = a[i];
    }

    // 预处理对数
    lg[1] = 0;
    for (int i = 2; i <= n; i++)
        lg[i] = lg[i >> 1] + 1;

    // 构建稀疏表
    for (int j = 1; (1 << j) <= n; j++) {
        for (int i = 1; i + (1 << j) - 1 <= n; i++) {
            f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
        }
    }

    q = quickRead();
    while (q--) {
        int L = quickRead();
        int R = quickRead();
        int l = lg[R - L + 1];
        int result = max(f[L][l], f[R - (1 << l) + 1][l]);
        cout << result << "\n";
    }

    return 0;
}
 

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

暑假来了,对于小美来说,想要锻炼身体,游泳还不够,小美想:她还必须要跑步。

为此,小美在家的周围设置了 n-1 个打卡点,小美每次跑步都需要把这 n-1 个打卡点全部打卡。

但是小美喜欢轻装上阵,所以小美出去跑步时从来不带水杯。

可是小美又容易口渴,所以每次小美打卡完一个打卡点后,都要返回到家中去喝水。

小美第一次出去打卡是从家出发的,小美最后一次打完卡还要回到家中喝水。

况且小美很自律,所以她一定会出去打 n-1 次不同的卡,即便在打卡路上遇到了另一个打卡点,她也不会打卡。

不过小美想:既然已经在假期坚持游泳了,那么跑步上可不可以偷偷懒呢。

所以小美想请聪明的你来帮她想想办法,让她跑步的总路程最短。

输入描述:

 

输出描述:

输出一个整数,表示跑步的最短总路程。

示例1

输入

复制4 6 1 2 2 2 4 4 1 4 1 4 3 2 3 1 5 1 3 3

4 6
1 2 2
2 4 4
1 4 1
4 3 2
3 1 5
1 3 3

输出

复制29

29

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m;int d[N],vis[N],di[N];
struct edge{
    int v,w;
};
vector<edge> e[N];
priority_queue<pair<int,int>>q;
void spfa(int s)
{
    memset(d,0x3f,sizeof d);
    memset(vis,0,sizeof vis);
    d[s]=0;q.push({0,s});
    while(q.size())
    {
        auto t=q.top();q.pop();
        int u=t.second;
        if(vis[u]) continue;
        vis[u]=1;
        for(auto ed:e[u])
        {
            int v=ed.v;int w=ed.w;
            if(d[v]>d[u]+w){
                d[v]=d[u]+w;
                q.push({-d[v],v});
            }
        }
    }
}
int spfa1(int s)
{
    memset(di,0x3f,sizeof di);
    memset(vis,0,sizeof vis);
    di[s]=0;q.push({0,s});
    while(q.size())
    {
        auto t=q.top();q.pop();
        int u=t.second;
        if(vis[u]) continue;
        vis[u]=1;
        for(auto ed:e[u])
        {
            int v=ed.v;int w=ed.w;
            if(di[v]>di[u]+w){
                di[v]=di[u]+w;
                q.push({-di[v],v});
            }
        }
    }
    return di[1];
}
int main()
{
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int x,y,z;
        cin>>x>>y>>z;
        e[x].push_back({y,z});
    }
    spfa(1);
    int h=0;
    for(int i=1;i<=n;i++)
    {
        h+=d[i];
    }
    for(int i=1;i<=n;i++)
    {
        h+=spfa1(i);
    }
    cout<<h<<endl;

 

 

  • 16
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值