【题解】牛客小白月赛12

文章目录

  • A - 华华听月月唱歌(贪心)
  • B - 华华教月月做数学(大数 / 快速幂+快速乘)
  • E - 华华给月月准备礼物(二分)
  • G - 华华对月月的忠诚(规律)


A - 华华听月月唱歌(贪心)

原题链接:https://ac.nowcoder.com/acm/contest/392/A

  • 思路:
    1. 先把所有区间按左端点从小到大排序,如果左端点相同,则按右端点从大到小排序。
    2. 遍历所有区间,如果有重合的区间则更新到右端点最远的区间;如果区间不重合则把左端点更新为该区间右端点的下一个数,判断下一个区间是否小于或者等于左端点,是的话,继续更新最远的右端点,否则出现了断点。
    3. 同时,如果开头或者结尾出现了断点则可直接输出 -1 。

Code(C++):

#include 
#include 
using namespace std;
const int N=1e5+10;
struct node{
    int l,r;
}a[N];
bool operator <(const node &a, const node &b){
    if(a.l==b.l)    return a.r>b.r;
    return a.l<b.l;
} 
int main(){
    int n,m;    cin>>n>>m;
    for(int i=1;i<=m;i++)
        cin>>a[i].l>>a[i].r;
    sort(a+1,a+1+m);
    if(a[1].l>1){
        cout<<-1<<endl;
        return 0;
    }
    int s=1,e=1,ans=1;
    for(int i=1;i<=m;i++){
        if(a[i].l<=s)    e=max(e,a[i].r);
        else{
            ans++;
            s=e+1;
            if(a[i].l<=s)    e=max(e,a[i].r);
            else{
                cout<<-1<<endl;
                return 0;
            }
        }
        if(e>=n)    break;
    }
    if(e>=n)    cout<<ans<<endl;
    else    cout<<-1<<endl;
    return 0;
}


B - 华华教月月做数学(大数 / 快速幂+快速乘)

原题链接:https://ac.nowcoder.com/acm/contest/392/B

  • 思路: 用 Java 的话直接调用 modPow() 函数即可,也可以用 Python 写个快速幂,用 C++ 的话就是快速幂 + 快速乘的模板题了。

Code(C++):

#include 
#define ll long long 
using namespace std;
ll q_mul(ll a, ll b, ll mod){
    ll ans=0,res=a;
    while(b){
        if(b&1)    ans=(ans+res)%mod;
        res=(res+res)%mod;
        b>>=1;
    }
    return ans;
}
ll q_pow(ll a, ll b, ll mod){
    ll ans=1,res=a;
    while(b){
        if(b&1)    ans=q_mul(ans,res,mod);
        res=q_mul(res,res,mod);
        b>>=1;
    }
    return ans;
}
int main(){
    int t;    cin>>t;
    while(t--){
        ll a,b,mod;    cin>>a>>b>>mod;
        cout<<q_pow(a,b,mod)<<endl;
    }
    return 0;
}

Code(Java):

import java.math.BigInteger;
import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int t = in.nextInt();
        while(t-- >0){
            BigInteger a = in.nextBigInteger();
            BigInteger b = in.nextBigInteger();
            BigInteger mod = in.nextBigInteger();
            BigInteger ans = a.modPow(b,mod);
            System.out.println(ans);
        }
    }
}

Code(Python):

t=int(input())
for i in range(0,t):
    s=input().split()
    a=int(s[0])
    b=int(s[1])
    p=int(s[2])
    res=1
    while(b>0):
        if(b&1):
            res=res*a%p
        a=a*a%p
        b>>=1
    res=res%p
    print(res)


E - 华华给月月准备礼物(二分)

原题链接:https://ac.nowcoder.com/acm/contest/392/E

  • 思路: 二分棍子的长度,根据截得的段数总和来判断是否满足要求。

Code(C++):

#include 
using namespace std;
const int N=1e5+10;
int n,k,a[N];
bool check(int x){
    int sum=0;
    for(int i=1;i<=n;i++)
        sum+=(a[i]/x);
    return sum>=k;
}
int main(){
    cin>>n>>k;
    int l=1,r=0;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        r=max(r,a[i]);
    }
    int ans=0;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid))    ans=mid,l=mid+1;
        else    r=mid-1;
    }
    cout<<ans<<endl;
}


G - 华华对月月的忠诚(规律)

原题链接:https://ac.nowcoder.com/acm/contest/392/G

  • 思路: gcd(a,b) == gcd(b,a%b) == gcd (b,a-b) ,再根据斐波那契数列的性质,可以知道只要对最开始两个数取其最大公约数即可。

Code(C++):

#include 
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b){
    return b==0?a:gcd(b,a%b);
}
int main(){
    ll a,b;    cin>>a>>b;
    cout<<gcd(a,b)<<endl;
    return 0;
}
//__gcd(a,b);


你可能感兴趣的:(【题解】牛客小白月赛12)