CF2189
A. Table with Numbers
code
#include<bits/stdc++.h>
using namespace std;
const int NN = 108;
int a[NN];
void solve(){
int n,h,l;
cin >> n >> h >> l;
if(h > l) swap(h,l);
for(int i = 1; i <= n; ++i) cin >> a[i];
sort(a+1,a+1+n);
int pos = upper_bound(a+1,a+1+n,h) - a,pos2 = upper_bound(a+1,a+1+n,l) - a;
int lw = pos - 1, up = pos2 - pos;
if(up > lw) cout << lw << '\n';
else cout << (up+lw) / 2 << '\n';
}
int main(){
ios::sync_with_stdio(false),cin.tie(0);
int T;
cin >> T;
while(T--){
solve();
}
}
B. The Curse of the Frog
tag: 贪心
我们首先把所有免费额度全部跳完 \(\sum a_i \times (b_i-1)\)
之后便是每次跳跃都会花费一个额度,向前跳 \(w_i = a_i \times b_i - c_i\)
所以每次贪心选择 \(w_i\) 最大的进行跳跃即可
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 2e18;
void solve(){
ll n,x;
cin >> n >> x;
ll now = 0,maxn = -INF;
for(int i = 1; i <= n; ++i){
ll a,b,c;
cin >> a >> b >> c;
now += a * (b-1);
maxn = max(a * b - c, maxn);
}
if(now >= x){
cout << "0\n";
return;
}
else{
if(maxn <= 0) cout << "-1\n";
else{
cout << (x - now + maxn - 1) / maxn << "\n";
}
}
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0);
int T;
cin >> T;
while(T--){
solve();
}
return 0;
}
C1. XOR Convenience (Easy Version)
直接让 \(a_n = 1\) 即可,剩下的 \(a_i = i \oplus 1(2\leq i \leq n-1)\)
code
#include<bits/stdc++.h>
using namespace std;
void solve(){
int n;
cin >> n;
if(n == 1){
cout << "1\n";
}
else if(n % 2 == 0){
cout << n << " ";
for(int i = 2; i < n; ++i){
cout << (i ^ 1) << " ";
}
cout << "1\n";
}
else{
cout << n-1 << " ";
for(int i = 2; i < n; ++i){
cout << (i ^ 1) << " ";
}
cout << "1\n";
}
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0);
int T;
cin >> T;
while(T--){
solve();
}
return 0;
}
C2. XOR-convenience (Hard Version)
如果 \(n\) 为奇数,那么 \(f_{n-1} = 1,\ f_1 = n-1,\ f_n = n,\ f_i = i \oplus 1\)
\(n\) 为 \(2^k\) 无解
如果 \(n\) 为偶数,C1 的基础上交换 \(a_1, a_{lowbit(n)}\) 即可
code
#include<bits/stdc++.h>
using namespace std;
const int NN = 2e5 + 8;
int a[NN];
inline int lowbit(int x){return x & (-x);}
int main()
{
ios::sync_with_stdio(false),cin.tie(0);
int T;
cin >> T;
while(T--){
int n;
cin >> n;
int m = n;
while((m&1) == 0){
m >>= 1;
}
if(m == 1 && n != 1) cout << -1 << '\n';
else if(n == 1){
cout << "1\n";
continue;
}
else if(n % 2 == 0){
for(int i = 2; i <= n-1; ++i){
a[i] = i ^ 1;
}
a[1] = n;
a[n] = 1;
swap(a[1],a[lowbit(n)]);
for(int i = 1; i <= n; ++i) cout << a[i] << " ";
cout << "\n";
}
else{
cout << n - 1 << " ";
for(int i = 2; i <= n-2; ++i){
cout << (i ^ 1) << " ";
}
cout << "1 " << n << '\n';
}
}
return 0;
}
D1. Little String (Easy Version)
tag: 计数 mex 排列
排列的区间 \(mex\) 等于其前缀和后缀的最小值
显然 \(s_1 = s_n = 1\),因为只选 \(0\) 的 \(mex\) 为 \(1\),什么都选的 \(mex\) 为 \(n\)
之后我们从大到小放入每一个数
- 若 \(s_i == 0\),那么就不能放在两端,得放中间 \(ans *= i-1\)
- 若 \(s_i == 1\),那么就需要放在两端,\(ans *= 2\)
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
const int NN = 2e5 + 8;
void solve(){
ll n,c;
cin >> n >> c;
ll ans = 1, ans2 = 1;
string s;
cin >> s;
s = ' ' + s;
if(s[1] == '0' || s[n] == '0') return cout << "-1\n", void(0);
for(ll i = n-1; i >= 1; --i){
if(s[i] == '1') ans = ans * 2 % MOD, ans2 = ans2 * 2 % c;
else{
if(i-1 == 0) return cout << "-1\n", void(0);
ans = ans * (i - 1) % MOD;
ans2 = ans2 * (i - 1) % c;
}
}
if(ans2 == 0) return cout << "-1\n", void(0);
cout << ans << '\n';
return;
}
int main(){
ios::sync_with_stdio(false),cin.tie(0);
int T;
cin >> T;
while(T--){
solve();
}
}
D2. Little String (Hard Version)
tag: 因数 贪心
首先 0 和 1 的贡献是固定的
我们现在主要减少问号的贡献
我们知道,将一个问号变成 \(1\) 有 \(2\) 的贡献
将一个问号变成 \(0\) 有 \(i-1\) 的贡献
若 \(i-1\) 为偶数,显然将这个问号变成 \(1\) 无论如何都更划算
若为奇数且 \(i-1 \neq 1\),则待定
我们对于不能是 \(c\) 的倍数这个条件,维护 \(c\) 和当前答案的 \(gcd\)
若做完以上操作后,\(c\) 不是 \(2\) 的次幂,那么待定的所有位都给出 \(2\) 的贡献
否则,贪心地让 \(i-1\) 更大的问号贡献 \(2\),直到 \(gcd = 2\)
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
const int NN = 2e5 + 8;
inline int gcd(int x,int y){
return x == 0 ? y : gcd(y % x, x);
}
vector<int> num;
int check(int x){
int cnt = 0;
while(!(x & 1)){
x >>= 1;
++cnt;
}
if(x == 1) return cnt;
else return -1;
}
void solve(){
ll n,c;
cin >> n >> c;
ll ans = 1;
string s;
cin >> s;
s = ' ' + s;
if(s[1] == '0' || s[n] == '0') return cout << "-1\n", void(0);
s[1] = s[n] = '1';
num.clear();
for(ll i = n-1; i >= 1; --i){
if(s[i] == '1') ans = ans * 2 % MOD, c = c / gcd(c, 2);
else if(s[i] == '0'){
ans = ans * (i - 1) % MOD;
c = c / gcd(c, i-1);
}
else{
if(i % 2 == 1) c = c / gcd(c,2), ans = ans * 2 % MOD;
else if(i-1 != 1) num.push_back(i-1);
}
}
if(c == 1) return cout << "-1\n", void(0);
ll numc = check(c);
if(numc >= 0){
for(int i = 0; i < min(numc - 1,(long long)num.size()); ++i){
ans = ans * 2 % MOD;
}
for(int i = numc - 1; i < num.size(); ++i){
ans = ans * num[i] % MOD;
}
cout << ans << '\n';
}
else{
for(int i = 1; i <= num.size(); ++i){
ans = ans * 2 % MOD;
}
cout << ans << '\n';
}
return;
}
int main(){
ios::sync_with_stdio(false),cin.tie(0);
int T;
cin >> T;
while(T--){
solve();
}
}
本文来自博客园,作者:ricky_lin,转载请注明原文链接:https://www.cnblogs.com/rickylin/p/19553194/CF2189

浙公网安备 33010602011771号