Codeforces Round 948 (Div. 2)(A-D题解)
Codeforces Round 948 (Div. 2)
2024-05-26 —yimg
A
签到题
代码:
#include<bits/stdc++.h>
using namespace std;
void work()
{
int n, m;
cin >> n >> m;
if(n < m){
cout << "NO\n";
return;
}
if((n - m)&1){
cout << "NO\n";
return;
}
else{
cout << "YES\n";
}
}
int main()
{
int t;
cin >> t;
while(t--)
work();
}
B
题意:
将一个正整数x进行特殊的二进制分解, 构造出长度为n的数组a,满足
思路:
正常的二进制分解我们很容易做到,可得到一个只含有0和1的数组a,本题多了一个限制条件
,不能有连续非0位,所以我们可以将连续的1位向高位进1,这段1的最低位补-1,值不变
代码:
#include<bits/stdc++.h>
using namespace std;
void work()
{
int x;
cin >> x;
vector<int> a(35);
int n = __lg(x);
int cnt = 0;
while(x){
a[cnt++] = x&1;
x >>= 1;
}
for(int i = 0; i <= n; ++i){
if(a[i] == 0) {
continue;
}
else{
int p = i;
for(; p <= n; ++p){
if(a[p] == 0) break;
}
if(p == i + 1) continue;
else{
a[i] = -1;
for(int j = i + 1; j < p; ++j)
a[j] = 0;
a[p] = 1;
i = p - 1;
}
}
}
cout << 32 << '\n';
for(int i = 0; i < 32; ++i){
cout << a[i] << ' ';
}
cout << '\n';
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
work();
}
C
题意:
给定数组a,为最长特殊子序列能有多长,
定义特殊子序列为:此段子序列的lcm在数组a中没有出现过
思路:(枚举)
-
若原数组的lcm如果大于数组最大值,则答案为n
-
若原数组的lcm不大于n, 特殊子序列的lcm一定时原数组lcm的因子 ( 因为子lcm 是由 原lcm 去除一些因子得到的 ), 我们可以枚举因子,若此因子没有出现过,并且原数组可以有元素的lcm等于此因子,统计这些元素的个数,取个数的max即为答案, 枚举因子个数可以估算为
到 ,时间复杂度为
代码:
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
void work()
{
int n;
cin >> n;
vector<int> a(n);
for(int i = 0; i < n; ++i)
cin >> a[i];
i64 x = 1;
for(int i = 0; i < n; ++i)
{
x = lcm(x, a[i]);
if(x > 1e9){
break;
}
}
auto it = find(a.begin(), a.end(), x);
if(it == a.end()){
cout << n << '\n';
return;
}
int ans = 0;
auto check = [&](int d){
if(find(a.begin(), a.end(), d) != a.end()){
return;
}
int lc = 1;
int cnt = 0;
for(int i = 0; i < n; ++i){
if(d % a[i] == 0){
cnt++;
lc = lcm(lc, a[i]);
}
}
if(lc == d){
ans = max(ans, cnt);
}
};
for(int i = 1; i * i <= x; ++i){
if(x%i == 0){
check(i);
check(x/i);
}
}
cout << ans << '\n';
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
work();
}
D
题意:
给定n * m 的01矩阵, 任意次行xor操作 : 将一整行全部异或1
问特殊列最大能有多少列,并给出操作方案
思路:(枚举, 哈希)
-
令任意格(i, j) 为1,则此时操作序列一定
-
枚举每个格子为1时的操作序列, 将操作序列进行哈希, 统计每种操作序列的特殊列数
-
实现上, 可以令一列全操作为0, 在逐行分别异或为1, 统计最大答案
代码:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
mt19937_64 rnd(time(0));
//mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count());
void work()
{
int n, m;
cin >> n >> m;
vector<vector<bool>> table(n, vector<bool>(m));
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j){
char c; cin >> c;
table[i][j] = c - '0';
}
vector<ll> rands(n);
for(int i = 0; i < n; ++i) rands[i] = rnd();
map<ll, int> num;
int res = 0;
pair<int, int> ans;
for(int j = 0; j < m; ++j){
ll summ = 0;
for(int i = 0; i < n; ++i){
if(table[i][j]){
summ ^= rands[i];
}
}
for(int i = 0; i < n; ++i){
summ ^= rands[i];
num[summ]++;
if(res < num[summ]){
res = num[summ];
ans = {i, j};
}
summ ^= rands[i];
}
}
cout << res << '\n';
int x = ans.first, y = ans.second;
for(int i = 0; i < n; ++i){
if(i == x) cout << (table[i][y] ? 0 : 1);
else cout << (table[i][y] ? 1 : 0);
}
cout << '\n';
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while(t--)
work();
}
分类:
ACM
标签:
ACM
, Codeforces
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】