B
- 题意: 一个序列,当你在i时,可以降低(a_i)来获得收益,也可以用升高(a_i).当(|a_i-a{i+1}|<k)才可以从(i转移到{i+1}),问能否到n.
- 思路: 贪心转移即可
if(a[i+1]-a[i]-k<=0){ // 可以转移,取a[i]
m += min(a[i]-a[i+1]+k,a[i]);
}else{ // 不可以转移,放a[i]
m -= max(a[i+1]-a[i]-k,0);
}
一开始写成
m-= a[i+1]-a[i]-k;
wa哭,关键在降低(a[i])时最多取(a[i])个.
C
- 题意: 两个扇形轮盘,分别隔板平均分成n,m份,每次询问询问两个区域是否可以相互到达
- 思路: 先求出(gcd(n,m)),然后n和m都除去gcd.这样就能得到每个相互连通块的区域个数,然后根据倍数关系判断是否在一个连通块即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define ll long long
using namespace std;
typedef pair<int,int> pii;
const int N = 1e5+10;
ll n,m,q;
int main(){
cin >> n >> m >> q;
ll k = __gcd(n,m);
n/=k; m/=k;
ll a,b,c,d;
bool sign = false;
for(int i=1;i<=q;++i){
cin >> a >> b >> c >>d;
sign = false;
int k1,k2;
if(a==1){
k1 = b/n;
if(b%n==0) k1--;
}else{
k1 = b/m;
if(b%m==0) k1--;
}
if(b==1){
k2 = d/n;
if(d%n==0) k2--;
}else{
k2 = d/m;
if(d%m==0) k2--;
}
if(k1==k2) cout <<"YES
";
else cout <<"NO
";
}
return 0;
}