Codeforces Round 924 (Div. 2) A-D

A. Rectangle Cutting

显然,要至少存在一条边的长度为偶数,才可以切割成两个完全一样的部分。

并且切完之后不能是正方形。

直接模拟即可。

#include <iostream>

using namespace std;

bool solve(){
    int a, b; cin >> a >> b;
    if(a&1 && b&1) return false;
    if(a & 1){
        if(b/2 == a) return false;
        return true;
    }
    if(b & 1){
        if(a/2 == b) return false;
        return true;
    }
    return true;
}

int main(){
    int _; cin >> _; while(_--) cout << (solve() ? "YES" : "NO") << '\n';
    return 0;
}

B. Equalize

双指针。因为要加的是一个 1 − n 1-n 1n 的排列,所以开始相同的元素加完不可能相同,因此先去重。

可以证明,若区间 [ l , r ] [l, r] [l,r] 的极差 d < n d < n d<n,则必然可以加成相同的数。

排序之后找极差小于 n n n 的最长连续区间即可。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void solve(){
    int n; cin >> n;
    vector <int> a(n); for(auto &x : a) cin >> x;
    sort(a.begin(), a.end()); int _n = unique(a.begin(), a.end()) - a.begin();
    int ans = 0;
    for(int l = 0, r = 0; l < _n; l++){
        while(r+1 < _n && a[r+1] - a[l] < n) r++;
        ans = max(ans, r - l + 1);
    }
    cout << ans << endl;
}

int main(){
    int _; cin >> _; while(_--) solve();
    return 0;
}

C - Physical Education Lesson

由题,

对于 k ∈ Z k \in \mathbb Z kZ,我们可以写出如下代码生成第 n n n 个数:

int calc(int n, int k){
     n--, k--;
     return ((n / k) % 2 == 0 ? 1 + (n%k) : k - (n%k) + 1);
}  

因此,对于一组 ( n , k , x ) (n, k, x) (n,k,x)

一定有 x = 1 + ( ( n − 1 ) % ( k − 1 ) ) x = 1 + ((n-1) \% (k-1)) x=1+((n1)%(k1)) x = ( k − 1 ) − ( ( n − 1 ) % k ) + 1 x = (k-1) - ((n-1) \% k) +1 x=(k1)((n1)%k)+1 成立。

即: k ∣ ( n − 1 ) + x − 1 k | (n-1)+x-1 k(n1)+x1 k ∣ ( n − 1 ) − x + 1 k | (n-1)-x+1 k(n1)x+1

所以枚举 ( n − 1 ) + ( x − 1 ) (n-1)+(x-1) (n1)+(x1) ( n − 1 ) − ( x − 1 ) (n-1)-(x-1) (n1)(x1) 的因子中符合条件的个数即为答案。

开个 set 记录即可。

#include <iostream>
#include <set>

#define int long long

using namespace std;

int n, x;
set <int> s;

bool check(int k){
    return k > 0 && (((n / k) & 1) == 0 ? 1 + (n%k) : k - (n%k) + 1) == x;
}

void calc(int p){
    for(int i = 1; i*i <= p; i++){
        if(check(i)) s.insert(i);
        if(check(p/i)) s.insert(p/i); 
    }
}

void solve(){
    s.clear(); cin >> n >> x; n--;
    calc(n+x-1);
    calc(n-x+1);
    cout << s.size() << '\n';
}

signed main(){
    int _; cin >> _; while(_--) solve();
    return 0;
}

D - Lonely Mountain Dungeons

答案是单峰的,可以用三分之类的做法来做。

但还有一种很优雅的根号做法:

参考题解:https://www.luogu.com.cn/blog/MaxBlaze/cf1928-ti-xie

由题 ∑ c i ≤ 2 × 1 0 5 \sum c_i \le 2 \times 10^5 ci2×105,又有 1 ≤ c i ≤ 2 × 1 0 5 1 \le c_i \le 2 \times 10^5 1ci2×105,可知不同的 c i c_i ci 最多有 2 × 1 0 5 \sqrt{2 \times 10^5} 2×105 种,去重后暴力计算答案即可。

#include <iostream>
#include <vector>
#include <algorithm>

#define int long long

using namespace std;

inline int C(int t){ return (t * (t-1)) >> 1; }

int calc(int s, int t){
    int ret = C(t - s % t) * (s / t) * (s / t)
            + C(s % t) * (s / t + 1) * (s / t + 1)
            + (t - s % t) * (s % t) * (s / t) * (s / t + 1);
    return ret;
}

const int maxn = 2e5 + 5;
int c[maxn], cnt[maxn];

void solve(){
    int n, b, x, sum = 0; cin >> n >> b >> x;
    for(int i = 1; i <= n; i++) cin >> c[i], sum += c[i], cnt[c[i]]++;
    sort(c+1, c+1+n); n = unique(c+1, c+1+n) - c - 1;
    int ans = 0;
    for(int i = 1; i <= sum; i++){
        int tmp = 0;
        for(int j = 1; j <= n; j++) tmp += cnt[c[j]] * calc(c[j], i) * b;
        ans = max(ans, tmp - (i-1)*x);
    }
    for(int i = 1; i <= n; i++) cnt[c[i]] = 0;
    cout << ans << '\n';
}

signed main(){
    int _; cin >> _; while(_--) solve();
    return 0;
}
  • 26
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值