A - 华华听月月唱歌(贪心)
- 思路:
- 先把所有区间按左端点从小到大排序,如果左端点相同,则按右端点从大到小排序。
- 遍历所有区间,如果有重合的区间则更新到右端点最远的区间;如果区间不重合则把左端点更新为该区间右端点的下一个数,判断下一个区间是否小于或者等于左端点,是的话,继续更新最远的右端点,否则出现了断点。
- 同时,如果开头或者结尾出现了断点则可直接输出 -1 。
Code(C++):
#include <iostream>
#include <algorithm>
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 - 华华教月月做数学(大数 / 快速幂+快速乘)
- 思路: 用 Java 的话直接调用 modPow() 函数即可,也可以用 Python 写个快速幂,用 C++ 的话就是快速幂 + 快速乘的模板题了。
Code(C++):
#include <iostream>
#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 - 华华给月月准备礼物(二分)
- 思路: 二分棍子的长度,根据截得的段数总和来判断是否满足要求。
Code(C++):
#include <iostream>
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 - 华华对月月的忠诚(规律)
- 思路: gcd(a,b) == gcd(b,a%b) == gcd (b,a-b) ,再根据斐波那契数列的性质,可以知道只要对最开始两个数取其最大公约数即可。
Code(C++):
#include <iostream>
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);