牛客周赛 Round 56

牛客周赛 Round 56

A 面包店故事

链接:https://ac.nowcoder.com/acm/contest/88392/A
来源:牛客网

题目描述

小镇上有一家面包店,面包以 𝑥 元的价格出售,加 𝑦 元可以多加几块培根。小歪带着
𝑛 元来到了面包店,他想知道自己能不能买到加培根的面包?

输入描述:

在一行上输入三个整数 𝑥,𝑦,𝑛(1≤𝑥,𝑦,𝑛≤100) 代表面包的价格、培根的价格和小歪带的钱。

输出描述:

如果小歪能加到培根,在一行上输出 𝑌𝐸𝑆 ;否则,直接输出 𝑁𝑂 。

示例1

输入
3 1 5
输出
YES

说明

面包加培根一共 4 元,小歪带了 5 元,他可以吃到培根!

示例2

输入
10 1 10
输出
NO

说明

面包加培根一共 11 元,小歪带了 10 元,他吃不到培根 (⋟﹏⋞) 。

题解

签到

#include<bits/stdc++.h>
using namespace std;
int x,y,n;
int main(){
    int i,j,k;
    cin>>x>>y>>n;
    if(x+y>n)printf("NO\n");
    else printf("YES\n");
    return 0;
}
B 放课后故事

链接:https://ac.nowcoder.com/acm/contest/88392/B
来源:牛客网

题目描述

小 𝑆 想要举办一个纸飞机大赛,他最新研制出的纸飞机需要 𝑘 张纸才能折成。
为了制作纸飞机,他向班里的 𝑛 个人要了一些纸,第 𝑖 个人提供了 𝑎𝑖 张纸给小 𝑆 研究纸飞机。 
放学了,小 𝑆 终于折好了全部的纸飞机,现在有 𝑚 个人留下来和小 𝑆 一起飞纸飞机。 最多有多少个人能分到纸飞机。

输入描述:

第一行输入三个整数 𝑛,𝑚,𝑘(1≤𝑛≤105; 0≤𝑚≤105; 1≤𝑘≤109) 代表班级同学数量、留下来的同学数量和叠一只纸飞机需要的纸的数量。
第二行输入 𝑛 个整数 𝑎1,𝑎2,…,𝑎𝑛(1≤𝑎𝑖≤109) 代表每一个同学提供的纸的数量。

输出描述:

在一行上输出一个整数,代表最多有多少个人能分到纸飞机。

示例1

输入
3 2 5
1 2 4
输出
1

说明

小 𝑆 一共收集到 7 张纸,只可以叠一架纸飞机。

示例2

输入
6 3 4
1 1 4 5 1 4
输出
4

说明

小 𝑆 一共收集到 16 张纸,可以叠 4 架纸飞机,每个人都能分到纸飞机。

题解

草率了,忘记小S自己也算一个,还有long long

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,k,sum,a[100005];
signed main(){
    int i,j;
    cin>>n>>m>>k;
    for(i=1;i<=n;i++){
        cin>>a[i];
        sum+=a[i];
    }
    cout<<min(sum/k,m+1)<<endl;
    return 0;
}
C 异或故事

链接:https://ac.nowcoder.com/acm/contest/88392/C
来源:牛客网

题目描述

给定 𝑡 组询问,76 每次询问都会给出一个正整数 𝑎 ,你需要在区间 [1,109]中找到两个正整数 𝑏 和 𝑐 ,使得 𝑏⊕𝑐=𝑎 。
 ⊕ 代表按位异或。

输入描述:

每个测试文件均包含多组测试数据。第一行输入一个整数 𝑇 (1≤𝑇≤105) 代表数据组数,每组测试数据描述如下:
  在一行上输入一个整数 𝑎 ( 1≤𝑎≤109 )代表76 给出的初始数字。

输出描述:

对于每一组测试数据,在一行上输出两个正整数,代表你找到的两个值。
 如果存在多个解决方案,您可以输出任意一个。

示例1

输入
3
1
5
4
输出
2 3
3 6
74 78

说明

对于第一组测试数据,(10)2 xor ⁡(11)2 = (01)2 ; 
对于第二组测试数据,(011)2xor (110)2=(101)2

题解

我不知道正解哈,位运算这块我学的不好
我想到的就是在取出比当前的数大的2的倍数T,然后输出T和T+a,但是好像不对,125分拿75分。
大佬有知道原因的和我说下吧/(ㄒoㄒ)/~~

#include<bits/stdc++.h>
using namespace std;

#define int long long
int T,a;
signed main(){
    int i,j,k;
    cin>>T;
    while(T--){
        cin>>a;
        int x=1;while(x<=a)x*=2;
        cout<<x<<" "<<x+a<<endl;
    }
    return 0;
}

然后这是正解:

#include<bits/stdc++.h>
using namespace std;

#define int long long
int T,n;
int lowbit(int x){
    return x&(-x);
}
signed main(){
    int i,j,k;
    cin>>T;
    while(T--){
        cin>>n;
        if(n==1)printf("2 3\n");
        else if(n==1000000000)printf("%d %d\n",lowbit(n),(n^lowbit(n)));
        else printf("%d 1\n",n^1);
    }
    return 0;
}
D 构造故事

链接:https://ac.nowcoder.com/acm/contest/88392/D
来源:牛客网

题目描述

小 𝑆 今天在数学课上学习了三角形,他回家立马拿出了自己的 𝑛 根火柴,想知道从这 𝑛 根火柴中任选 3 根,能否组成一个周长最大的三角形。
 由于小 𝑆 只会暴力枚举,所以他把这个问题交给了你,你能帮他解决这个问题吗?

输入描述:

每个测试文件均包含多组测试数据。第一行输入一个整数 𝑇(1≤𝑇≤20) 代表数据组数,每组测试数据描述如下:
 第一行输入一个整数 𝑛(3≤𝑛≤104) 代表小 𝑆 的火柴数量。
 第二行输入 𝑛 个整数 𝑎1,𝑎2,…,𝑎𝑛(1≤𝑎𝑖≤109) 代表每根火柴的长度。

输出描述:

对于每一组测试数据,在一行上输出一个整数,代表能组成周长最大三角形的周长;如果无论如何都无法组成三角形,直接输出 −1 。

示例1

输入
3
6
2 2 10 4 10 6
5
6 1 5 3 3
5
2 2 4 10 6
输出
26
14
-1

说明

对于第一组测试数据,有两个合法的三角形 (4,10,10) 和 (6,10,10) 。

题解

排序然后选最大的三个比较能不能构成

#include<bits/stdc++.h>
using namespace std;
#define int long long 
int T,n,a[10005];
signed main(){
    int i,j,k;
    cin>>T;
    while(T--){
        cin>>n;
        for(i=1;i<=n;i++){
            cin>>a[i];
        }
        sort(a+1,a+1+n);
        for(i=n;i>=3;i--){
            if(a[i]<a[i-1]+a[i-2])
                break;
        }
        if(i==2)printf("-1\n");
        else cout<<a[i]+a[i-1]+a[i-2]<<endl;
    }
    return 0;
}
E 约会故事

链接:https://ac.nowcoder.com/acm/contest/88392/E
来源:牛客网

题目描述

情人节才刚刚过去没多久啊 (¯﹃¯∗) ,但是我们的 𝑥𝑞𝑞 已经开始备战明年的情人节了。心灰意冷的他找到小 𝑆 生成了一个虚拟对象小 𝐶 ,在一次次的模拟约会中达成“一起进入电影院”的人生成就。
𝑥𝑞𝑞 决定向小 𝐶 发送邀请。在设定中,下述情况的小 𝐶 会残忍的拒绝 𝑥𝑞𝑞 的邀请:
 ● 𝑥𝑞𝑞 不在 00:00 后、01:59 前(含)这段小 𝐶 的睡前手机时间里发送邀请;
 ● 𝑥𝑞𝑞 如果在小 𝐶 不开心时发送邀请;
接受了邀请还远远没有成功!在设定中,下述情况的小 𝐶 会在进入电影院前离去: 
● 𝑥𝑞𝑞 到电影院的时间比小 𝐶 晚;
● 𝑥𝑞𝑞 给小 𝐶 准备的奶茶不是她喜欢的。
 如果小 𝐶 同意了邀请,且没有中途离去,我们视为 𝑥𝑞𝑞 达成成就!让我们一起来判定——这一次, 𝑥𝑞𝑞 会成功吗。

输入描述:

第一行输入两个整数 𝑛,𝑚(1≤𝑛,𝑚≤105) 代表小 𝐶 感到开心的时间段数量和小 𝐶 喜欢的奶茶数量。
此后 𝑛 行,第 𝑖 行输入两个长度为 5 ,且形如 ℎℎ:𝑚𝑚 的字符串代表小 𝐶 第 𝑖 段感到开心的起止时间,保证每一段开心时间不超过 24 小时。除了这 𝑛 个时间段外,剩余时间她都是不开心的。 
第 𝑛+1 行输入 𝑚 个长度不超过 10 且由大小写字母混合构成的字符串 𝑠1,𝑠2,…,𝑠𝑚 代表小 𝐶 喜欢喝的奶茶名字。
第 𝑛+2 行输入一个整数 𝑞(1≤𝑞≤105) 代表 𝑥𝑞𝑞 尝试次数,每次尝试描述如下:
● 第一行输入一个长度为 5,且形如 ℎℎ:𝑚𝑚 的字符串代表 𝑥𝑞𝑞 发送邀请的时间点;
● 第二行输入两个长度为 5 ,且形如 ℎℎ:𝑚𝑚 的字符串代表 𝑥𝑞𝑞 到达电影院的时间和小 𝐶 到达电影院的时间,我们约定,他们会在同一天内到达;
● 第三行输入一个长度不超过 10 且由大小写字母混合构成的字符串 𝑡 代表 𝑥𝑞𝑞 购买的奶茶名字。
 本题中出现的时间格式均按照 𝐼𝑆𝑂8601 的二十四小时格式标准,即形如 ℎℎ:𝑚𝑚,其中
ℎℎ(00≤ℎℎ<24) 代表小时数,𝑚𝑚(00≤𝑚𝑚<60) 代表分钟数。

输出描述:

对于每一次尝试,如果 𝑥𝑞𝑞 成功达成成就,在一行上输出 Winner xqq ;如果 𝑥𝑞𝑞 成功邀请但是小 𝐶 中途离开,在一行上输出 Joker xqq ;否则,直接输出 Loser xqq 。

示例1

输入
3 2
00:03 00:47
00:30 01:23
12:00 17:00
Lemonade Cappuccino
5
00:35
12:00 12:00
Cappuccino
01:23
13:00 12:59
Cappuccino
01:15
11:00 12:43
WaTer
01:24
09:24 11:00
Lemonade
23:59
08:00 07:43
LeMonade
输出
Winner xqq
Joker xqq
Joker xqq
Loser xqq
Loser xqq

说明

对于第一次尝试:
● 𝑥𝑞𝑞 在 00:35 发送邀请,此时在规定时间内,且小 𝐶 是开心的,所以他的邀请会被接受;● 𝑥𝑞𝑞 在 12:00 到达电影院,此时不晚于小 𝐶 ,且携带了小 𝐶 爱喝的 𝐶𝑎𝑝𝑝𝑢𝑐𝑐𝑖𝑛𝑜 ,所以她不会中途离开。 
对于第二次尝试,由于迟到了,小 𝐶 中途离开; 
对于第三次尝试,由于带错了奶茶,小 𝐶 中途离开;
 对于第四次尝试,由于发送邀请时小 𝐶 不开心,所以邀请失败;
 对于第五次尝试,由于发送邀请时不在规定时间内,所以邀请失败。

示例2

输入
3 1
00:00 00:00
22:47 23:59
23:58 00:17
AbCdEfGhIj
1
00:00
00:00 00:00
AbCdEfGhIj
输出
Winner xqq

说明

注意,当开心的起始时间和结束时间相等时,我们认为小 𝐶 一整天都感到开心。

题解

模拟,但是!!!
我有一堆话想说!!!!
首先,你大半夜的发短信骚扰别人睡觉!
其次,这个小C这个心情冷热无常!你不行你换一个???
然后,等不了1分钟的女朋友你要了干啥!!!
最后,你在现实中你家女朋友这么多次实验??!!!
纯属的无聊题!!!
上代码

#include<bits/stdc++.h>
using namespace std;
int n,m,q,hh,mm,t[100005],tag;
string s;
int tim(int hh,int mm){
    return hh*60+mm;
}
unordered_map<string,bool>mp;
int main(){
    int i,j,k;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++){
        scanf("%d:%d",&hh,&mm);
        int tmp=tim(hh,mm);t[tmp]++;
        scanf("%d:%d",&hh,&mm);
        if(tmp>tim(hh,mm))tag++;
        t[tim(hh,mm)+1]--;
    }
    for(i=1;i<100000;i++)t[i]+=t[i-1];
    for(i=0;i<100000;i++)t[i]+=tag;
    for(i=1;i<=m;i++)
    {
        cin>>s;
        mp[s]=true;
    }
    scanf("%d",&q);
    while(q--){
        int flag=2;
        scanf("%d:%d",&hh,&mm);
        if(hh>1||!t[tim(hh,mm)])flag=0;
        scanf("%d:%d",&hh,&mm);
        int tmp=tim(hh,mm);
        scanf("%d:%d",&hh,&mm);
        
        if(tmp>tim(hh,mm)&&flag)flag=1;
        
        cin>>s;if(!mp.count(s)&&flag)flag=1;
        if(flag==2)printf("Winner xqq\n");
        else if(flag==1)printf("Joker xqq\n");
        else printf("Loser xqq\n");
    }
    return 0;
}
F 不是烤串故事

链接:https://ac.nowcoder.com/acm/contest/88392/F
来源:牛客网

题目描述

小红有两个长度为 𝑛 的字符串 𝑠 和 𝑡 ,我们定义下标从 1 开始,现在你可以选取字符串
𝑠 的前 𝑖 个字符 𝑠1𝑠2⋯𝑠𝑖 ,然后将这一部分反转后与剩余部分拼接,得到 𝑠𝑖′ 。
 请你找到每一个翻转前缀 𝑠𝑖′ 与字符串 𝑡 的 max ⁡ i = 1 n _ len ⁡ { lcp ⁡ ( s i ′ , t ) } \max _{i=1}^{n} \_\operatorname{len}\left\{\operatorname{lcp}\left(s_{i}^{\prime}, t\right)\right\} i=1maxn_len{lcp(si,t)},即长度最长的 lcp(𝑠𝑖′,𝑡) 。在这里,lcp 代表最长公共前缀。
 好吧,这其实并不难,作为神秘的 𝐹 题,你同时需要输出满足上述条件的最小的 𝑖 。
在本题中,反转即为将字符串绕中心字符前后反转,具体地说,设字符串为 𝑠1𝑠2⋯𝑠𝑛−1𝑠𝑛 ,反转后得到 𝑠𝑛𝑠𝑛−1⋯𝑠2𝑠1

输入描述:

每个测试文件均包含多组测试数据。第一行输入一个整数 𝑇 (1≤𝑇≤100) 代表数据组数,每组测试数据描述如下:
 第一行输入一个整数 𝑛(1≤𝑛≤106) 代表字符串长度。 
第二行输入一个长度为 𝑛 ,且仅由小写字母构成的字符串 𝑠。
 第三行输入一个长度为 𝑛 ,且仅由小写字母构成的字符串 𝑡。
 除此之外,保证所有的 𝑛 之和不超过 106

输出描述:

对于每一组测试数据,在一行上输出两个整数,代表最长 lcp 长度和在此条件下最小的
𝑖 。

示例1

输入
3
6
baabaa
aabbbb
3
abc
bac
2
ab
cd
输出
4 3
3 2
0 1

说明

对于第一组测试数据,我们这样描述整个过程: 
∙ 选择前缀长度为 1 翻转 𝑠1′=“𝑏𝑎𝑎𝑏𝑎𝑎” ,lcp = 0 ;
∙ 选择前缀长度为 2 翻转 𝑠2′=“𝑎𝑏𝑎𝑏𝑎𝑎” ,lcp⁡ = 1 ; 
∙ 选择前缀长度为 3 翻转 𝑠3′=“𝑎𝑎𝑏𝑏𝑎𝑎” ,lcp = 4 ;
∙ 选择前缀长度为 4 翻转 𝑠4′=“𝑏𝑎𝑎𝑏𝑎𝑎” ,lcp ⁡= 0 ; 
∙ 选择前缀长度为 5 翻转 𝑠5′=“𝑎𝑏𝑎𝑎𝑏𝑎” ,lcp = 1 ; 
∙ 选择前缀长度为 6 翻转 𝑠6′=“𝑎𝑎𝑏𝑎𝑎𝑏” ,lcp = 3 ;
 所以最长的公共前缀为 4 ,与此同时最小的翻转下标为 3 。

题解

在这里插入图片描述

#include<bits/stdc++.h>

using i64 = long long;
using u64 = unsigned long long;

const int P=13331;
const i64 hash_mod = 1610612741;

void solve() {
    int n;
    std::cin >> n;

    std::string s, t;
    std::cin >> s >> t;
    s = ' ' + s, t = ' ' + t;
    std::vector<i64> h1(n + 1), h2(n + 1), h3(n + 1), p(n + 1); 

    p[0] = 1, h1[0] = 0, h3[0] = 0;
    for (int i = 1; i <= n; i++) {
        p[i] = p[i - 1] * P % hash_mod;	
        h1[i] = (h1[i - 1] * P + s[i]) % hash_mod; 
        h3[i] = (h3[i - 1] * P + t[i]) % hash_mod;
    }
    h2[0] = 0;
    std::reverse(s.begin() + 1, s.end());
    for (int i = 1; i <= n; i++) {
        h2[i] = (h2[i - 1] * P + s[i]) % hash_mod; 
    }

    auto get = [&] (int l, int r, std::vector<i64>& h) -> i64 {
        return ((h[r] - h[l - 1] * p[r - l + 1]) % hash_mod + hash_mod) % hash_mod;
    };

    int mx = 0, pos = 1;
    for (int i = 1; i <= n; i++) {
        int l = 1, r = n;
        int ans = -1;
        while(l <= r) {
            int mid = l + r >> 1;
            i64 tar = get(1, mid, h3);
            i64 num = 0;
            if (mid > i) {
                num = get(i + 1, mid, h1);
                num = (num + get(n - i + 1, n, h2) * p[mid - i]) % hash_mod;
            }
            else {
                num = get(n - i + 1, n - i + mid, h2);
            }

            if (tar == num) {
                l = mid + 1;
                ans = mid;
                if (mid > mx) {
                    mx = mid;
                    pos = i;
                }
            }
            else {
                r = mid - 1;
            }
        }
    }

    std::cout << mx << ' ' << pos << '\n'; 
}

signed main() {
    std::ios::sync_with_stdio(0);
    std::cout.tie(0);
    std::cin.tie(0);

    i64 t = 1; 
    std::cin >> t;
    while (t--) {
        solve();
    }
} 
总结

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洋洋的计算机刷题日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值