A. Rectangle Cutting
思路分析:
分类讨论,对于一个矩形,如果两个变都是奇数,不可分割重组,自然不会出现新矩形,如果只存在一个偶数边且偶数边的大小是技术变得二倍只有一种分割方法且分割重组之后的矩形河原来一样,不可行,其余可行;
代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
int n;
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
cin >> n;
while(n--)
{
int a,b;
cin >> a >>b;
if(a<b)swap(a,b);
if(a%2 && b%2)
{
cout<<"No"<<'\n';
}
else if(a==2*b && b%2)
{
cout<<"No"<<'\n';
}
else
cout<<"Yes"<<'\n';
}
}
B. Equalize
思路分析:
枚举,先对原数组进行排序去重之后,以每个元素为起点二分查找找到最长的满足题意的子序列,比较即可,时间复杂度O(nlgn)
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n;
void solve()
{
cin >> n;
vector<int>a(n);
for(int i = 0;i<n;i++)
cin >> a[i];
sort(a.begin(),a.end());
a.erase(unique(a.begin(),a.end()),a.end());
int ans = 0;
for(int i = 0;i<a.size();i++)
{
int x = a[i] + n-1;
// cout<<x<<endl;
int u = upper_bound(a.begin(),a.end(),x)-a.begin()-i;
ans = max(ans, u);
// cout<<ans<<endl;
}
cout<<ans<<'\n';
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int T;
cin >>T;
while(T--)solve();
}
C. Physical Education Lesson
思路分析
通过观察可以发现原数列以(2*k-2)为一个周期,满足题意的位置有两类,一种是在上升区间找到的,另一种是在下降区间找到的,x-y和x+y-2的所有偶因数中大于2*k-2的数量
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5 + 10;
int n;
set<ll> work(ll x,ll y) {
set<ll>se;
for(int i = 1;i*i<=x;i++)
{
if(x%i==0){
if(i%2==0)se.insert(i);
if(x/i%2==0)se.insert(x/i);
}
}
for(int i = 1;i*i<=y;i++)
{
if(y%i==0){
if(i%2==0)se.insert(i);
if(y/i%2==0)se.insert(y/i);
}
}
return se;
}
void solve() {
ll x, y;
cin >> x >> y;
if (y > x) {
cout << 0 << '\n';
return;
}
ll u = 2*y-2;
ll p = x-y,q = x+y-2;
set<ll>se = work(p,q);
ll ans = 0;
for(auto i:se) {
// cout<<i<<" ";
if (i >= u)ans++;
}
cout<<ans<<'\n';
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int T;
cin >> T;
while (T--)solve();
}
D. Lonely Mountain Dungeons
思路分析
枚举分组数量,组合数计算之后比较即可。
代码
#include <iostream>
#include <vector>
#include <algorithm>
#define ll long long
using namespace std;
inline ll C(ll t) { return (t * (t - 1)) >> 1; }//计算C(n,2)
ll calc(ll s, ll t) {
//s个人分成t组
ll 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 N = 2e5 + 5;
ll c[N], cnt[N];
void solve() {
int n, b, x;
ll sum = 0;
cin >> n >> b >> x;
for (int i = 1; i <= n; i++) cin >> c[i], sum = max(sum,c[i]), cnt[c[i]]++;
//sum表示最大的组数
sort(c + 1, c + 1 + n);
n = unique(c + 1, c + 1 + n) - c - 1;
ll ans = 0;
for (int i = 1; i <= sum; i++) {//暴力枚举,找到兵力最大的分配组数
ll tmp = 0;
for (int j = 1; j <= n; j++) tmp += cnt[c[j]] * calc(c[j], i) * b;
ans = max(ans, tmp - 1ll*(i - 1) * x);
}
for (int i = 1; i <= n; i++) cnt[c[i]] = 0;
cout << ans << '\n';
}
int main() {
int _;
cin >> _;
while (_--) solve();
return 0;
}