牛客练习赛43 回顾

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

题目描述

这次 Tachibana Kanade 来到了一个神奇的学校参观,她发现了一些有趣的事情。
这个学校的所有人脾气都十分的古怪:每个人都有两个属性 aiai 和 bibi,每个人都想和除他以外所有 j 满足 ai+bi=ajai+bi=aj 的人搞好关系。我们定义一对人的关系是好的,当且仅当这两个人互相想与对方搞好关系。
现在给出这 n 个人的属性,Tachibana Kanade 想知道,这些人会不会有至少一对人的关系是好的。

输入描述:

第一行输入一个整数 n ,表示人的个数。
接下来 n 行,每行两个整数 ai,biai,bi,意义如「题目描述」所述。

输出描述:

如果存在至少一对人的关系是好的,那么输出 `YE5`,否则输出 `N0`。
示例1

输入

复制
5 
2 -10 
3 10 
0 5 
5 -5 
10 1

输出

复制
YE5

说明

第三个和第四个人关系好。

简单的枚举题。

直接 O(n2)O(n2) 枚举每对人判断是否成立即可。

注意到输出的字符串为 YE5 和 N0 即可通过此题。

#include<iostream>
using namespace std;
int a[105][3];
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i][0]>>a[i][1];
        a[i][2]=a[i][0]+a[i][1];
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(i!=j){
                if(a[i][2]==a[j][0]&&a[j][2]==a[i][0]){
                    cout<<"YE5"<<endl;
                    return 0;
                }
            }
        }
    }
    cout<<"N0"<<endl;
    return 0;
} 

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

题目描述

立华奏在学习初中数学的时候遇到了这样一道大水题:
“设箱子内有 n 个球,其中给 m 个球打上标记,设一次摸球摸到每一个球的概率均等,求一次摸球摸到打标记的球的概率”
“emmm...语言入门题”
但是她改了一下询问方式:设最终的答案为 p ,请输出 p 小数点后 K1K1 到 K2K2 位的所有数字(若不足则用 0 补齐)

输入描述:

第一行一个整数 T,表示有 T 组数据。
接下来每行包含四个整数 m,n,K1,K2m,n,K1,K2,意义如「题目描述」所示。

输出描述:

输出 T 行,每行输出 K2K1+1K2−K1+1 个数,表示答案。
注意同行的数字中间不需要用空格隔开。
示例1

输入

复制
5
2 3 2 3
1 7 1 7
2 5 1 3
12345 54321 3 10
12345 54321 100000 100010

输出

复制
66
1428571
400
72601756
78428232175

备注:

1mn109,1K1K21091≤m≤n≤109,1≤K1≤K2≤109;
0K2K1105,T200≤K2−K1≤105,T≤20。
作者:RainAir
链接:https://ac.nowcoder.com/discuss/173818
来源:牛客网

简单的模拟题。

题目等价于求分数 ab 的小数点后 K1K2位的所有数字。

直接暴力模拟除法过程是肯定会 T 的,但是我们发现我们不用从头开始模拟,只需要从 K1K1 位开始模拟就可以了。

直接通过快速幂+取模算出第 K1 位的数字。然后我们发现 K2K1105,所以暴力枚举除法过程就可以。

时间复杂度 O(n)

因为m<n,小数点后第i位是(m*10^i)%n
先快速幂求到x-1位,再枚举就可以了,我又傻逼了
#include<iostream>
using namespace std;
long long int n,m,t,x,y;
long long quick(long long a,long long b,long long c){
    long long ans=m;
    while(b){
        if(b&1) ans=(ans*a)%c;
        a=(a*a)%c;
        b>>=1;
    }
    return ans;
}
int main(){
    
    cin>>t;
    while(t--){
        cin>>m>>n>>x>>y;
        m=quick(10%n,x-1,n);
        for(x;x<=y;x++){
            m*=10;
            cout<<m/n;
            m%=n;
        }
            cout<<endl;
    }

    return 0;
}

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

题目描述

立华奏是一个刚刚开始学习 OI 的萌新。
最近,实力强大的  QingyuQingyu 当选了 IODS 9102 的出题人。众所周知, IODS 是一场极其毒瘤的比赛。为了在这次比赛中取得好的成绩,立华奏决定学习可能考到的每一个知识点。
在 QingyuQingyu 的博客中,立华奏得知这场比赛总共会考察选手 n 个知识点。此前,立华奏已经依靠自学学习了其中 k 个知识点。接下来,立华奏需要学习其他的知识点,每学习一个单独的知识点,需要消耗的时间为 TiTi 天。同时,某些知识点之间存在联系,可以加速学习的过程。经过计算,立华奏一共发现了其中 m 种联系,第 i 种联系可以表示为(Xi,Yi,Hi)(Xi,Yi,Hi),其含义为“在掌握了第 XiXi 个知识点和第 YiYi 个知识点中任意一个后,学习 HiHi 天即可掌握另一个知识点”。
留给立华奏的时间所剩无几,只有 t 天,因此,她想知道自己能不能在这 t 天内学习完成所有的知识点。

输入描述:

本题输入量较大,请注意使用效率较高的读入方式
输入的第一行包含四个整数 n, m, k, t,含义见上所述。
接下来一行,包含 n 个整数,依次表示  T1,T2,,TnT1,T2,⋯,Tn
接下来一行,包含 k 个整数,表示立华奏已经学习过的知识点。如果 k=0,则此处为一空行。
接下来 m 行,每行 3 个整数 Xi,Yi,HiXi,Yi,Hi,描述一种联系。

输出描述:

如果立华奏能够学习完所有的知识点,输出一行 Yes。否则输出 No
示例1

输入

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

输出

复制
Yes

说明

立华奏已经学习过了第 2, 3 个知识,由第 2 个关系,立华奏可以花 2 天学会知识点 1,在由关系 3, 立华奏可以 2 天学会知识点 4,因此总共需要花费 4 天,可以完成任务。
示例2

输入

复制
5 4 0 12
4 5 6 7 1

1 2 3
1 3 2
3 4 2
1 5 233

输出

复制
Yes

说明

立华奏比较菜,因此什么都没有学过。她可以选择先花 4 天的时间学会知识点 1。然后根据关系 1, 2,分别花 3, 2 天的时间学会知识点 2, 3,再根据关系 3,花 2 天的时间学会知识点 4。然后,她再单独学习知识点 5,花费1天,总共花费了 12 天 ,可以完成任务。

请注意,虽然关系 4 允许立华奏在知识点 1 的基础上学习知识点 5,但需要的时间比单独学习还要多,因此立华奏不会在知识点 1 的基础上学习知识点 5.

备注:

0kn106,m5×106,t1018,Ti,Hi103

作者:RainAir
链接:https://ac.nowcoder.com/discuss/173818
来源:牛客网

C. Review还不会,先标记一下

简单的图论题。

首先,我们考虑最简单的情况,即k=0k=0。然后,为了判定答案是否合法,我们考虑求出学完所有知识点的最小用时。考虑到一个知识点yy只能被下列两种途径学会:

  • 单独学习这一个知识点,耗时TyTy
  • 从某个已经学会的知识点xx中学习得来,耗时HxyHxy

如果我们新建一个“虚拟知识点”GG,并假设它刚开始便已经学会。那么,我们可以将第一种方案转化为第二种方案,即HGyHGy。而学会所有知识点,本质上就是将所有知识点联通,即求出原图的最小生成树即可。

下面,我们再考虑k>0k>0。我们可以再次使用虚拟节点GG,如果这个知识点初始时就已经学过,则只需要将其向虚拟节点GG连接一条边权为0的边,即可达到要求。

时间复杂度O((m+k)log(m+k))O((m+k)log⁡(m+k))。

当然这时肯定会有人怒斥出题人“你的题怎么卡常啊”。

std写道这一步已经通过了,但考虑到一些选手可能没有写读入优化的习惯,因此我们可以进一步优化。

  1. 注意到每条边的边权在103103以内,因此我们可以将Kruskal算法中的快速排序改为计数排序,砍掉排序的一个log,
  2. 结合并查集的路径压缩与启发式合并,可以O((m+k)α(m+k))O((m+k)α(m+k))解决此题。
  3. 注意到如果在计算某一条边时,你所消耗的时间已经超过了 TT,那么可以直接跳过。
  4. 同理,注意到 t1018t⩽1018 ,但是如果 tt 超过了 103×103×边数, 答案一定为 Yes

实际只需要第2个优化,便可以轻松通过此题。

#include<bits/stdc++.h>
using namespace std;
#define F(i,a,b) for(int i=a;i<=(b);++i)
#define F2(i,a,b) for(int i=a;i<(b);++i)
#define dF(i,a,b) for(int i=a;i>=(b);--i)
#define MN 1000005
#define ll long long
#define MM 6000005
int n,m,k,c;ll t,ans;
int T[MN],f[MN];
int ff(int x){return f[x]?f[x]=ff(f[x]):x;}
struct edg{int u,v,w;}e[MM];
int read()
{
    ll x=0;char s=getchar();
    while(s<'0'||s>'9'){s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x;
}
int main(){
    int x,y,z;
    n=read(),m=read(),k=read();scanf("%lld",&t);
    F(i,1,n)T[i]=read();
    F(i,1,k)T[read()]=0;
    F(i,1,n)e[++c]=(edg){n+1,i,T[i]};
    F(i,1,m)x=read(),y=read(),z=read(),e[++c]=(edg){x,y,z};
    sort(e+1,e+c+1,[](edg i,edg j){return i.w<j.w;});
    F(i,1,c){
        int u=ff(e[i].u),v=ff(e[i].v);
        if(u!=v){
            f[u]=v;
            ans+=e[i].w;
        }
    }puts(ans<=t?"Yes":"No");
    return 0;
}

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

题目描述

立华奏是一个天天打比赛的 OIer。
有一天,立华奏正在打一场比赛,菜爆了的立华奏依靠运气解决了大部分的题目,还有最后一道题目没有解决。
这道题目给定了两个长度为 n 的序列 {ai}, {bi},要求两个长度为 n 的 0/1 序列 {ci}, {di},最大化:
min{ni=1aici,ni=1bidi}ni=1cini=1dimin{∑i=1naici,∑i=1nbidi}−∑i=1nci−∑i=1ndi

输入描述:

输入的第一行包含一个整数 n。
接下来一行,包含 n 个整数,表示序列{ai}
接下来一行,包含 n 个整数,表示序列{bi}

输出描述:

输出的第一行包含一个整数,表示式子的最大值。
接下来一行,包含 n 个整数,表示你构造的序列 {ci}
接下来一行,包含 n 个整数,表示你构造的序列 {di}
如果有多种构造方法,你只需要输出任意一种。
示例1

输入

复制
3
100000 -100000 100000
-100000 100000 -100000

输出

复制
99998
0 0 1
0 1 0

备注:

n105,|ai|,|bi|105

作者:RainAir
链接:https://ac.nowcoder.com/discuss/173818
来源:牛客网

D.Sequence不会啊

简单的贪心题。最后一个测试点专门卡了一下n=0n=0可能让部分dalao的体验极差……出题人在此谢罪qwq

题目的含义其实是可以从{a},{b}{a},{b}中选出若干个数,选择一个数代价为11,你的利益为你{a}{a}和{b}{b}利益中的最小值。最大化你的利益。

我们记A=ni=1aici,B=ni=1bidi,K=ni=1ci+ni=1diA=∑i=1naici,B=∑i=1nbidi,K=∑i=1nci+∑i=1ndi,答案为min{A,B}Cmin{A,B}−C

一个显然的贪心策略,是将两个序列从大到小排序,然后考虑A,BA,B中较小的那一个,从它所对应的序列(AA对应aiai,BB对应bibi)中选出最大的没有被选的一个数,将它选中,直到我们找不到一个大于11的数。

下面我们来考虑这种贪心的正确性。假设我们在{ai}{ai}中选择了k1k1个数ai1,ai2,,aik1ai1,ai2,⋯,aik1,{bi}{bi}中选择了k2k2个数bj1,bj2,,bjk2bj1,bj2,⋯,bjk2,记这种取数方案为G(I,J)G(I,J),其中I={i1,i2,,i

转载于:https://www.cnblogs.com/yfr2zaz/p/10660454.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值