A. Row
时间:2024-07-08
原题:Codeforces Round 484 (Div. 2) A. Row
题意
给一串字符串有01组成,1边上不能有1,0边上不能没有1,如果满足输出yes
思路
就,一个一个遍历过来,写这题主要因为需要看清题目,注意如果只有一个“0”需要输出no,因为没有1
A. Alice and Bob
时间:2024-07-08
原题:Codeforces Round 201 (Div. 1) A. Alice and Bob
题意
给一个正整数序列 \(Arr\) ,每次AB需要取其中的两个数字,使得 \(|x_i-x_j|\notin Arr\) ,然后加入其中,输出赢家
思路
一开始以为是看范围内的没被使用过的整数个数,然后发现在2的时候会出问题
当时完全没有思路,所以用上了一直没用过的对拍器
发现是看范围内gcd的公倍数的个数,调了许久才发现。。。
D. Ehab the Xorcist
时间:2024-07-08
原题:Codeforces Round 628 (Div. 2) D. Ehab the Xorcist
题意
给两个数 \(u\) 和 \(v\) ,需要求一个最短数组\(Arr\),使所有的 \(x\) 相加等于 \(v\) ,异或起来等于 \(u\) ,\(x \in Arr\)
思路
首先尝试几次,发现最短数组的长度要么是2要么是3,然后寻找导致不同的原因
发现的做题思路是先获取 \(dif=v-u\) ,先将 \(dif\) 除2(除不了2说明不行)
所以最短数组要么是3,就是 \(u\) 本身和两个 \(dif/2\)
要么是2,就是 \(dif/2\) 的所有1位置在\(u\)的对应位置上都为0,那么答案就是 \(u+dif/2\) 和 \(dif/2\)
我觉得这题本质上是考对位数处理的代码能力,和一些对数字的敏感度
代码
int u, v;
int difdig[65];
int udig[65];
void solve() {
cin >> u >> v;
if (u == 0 && v == 0) {
cout << 0 << endl;
return;
}
if (u == v) {
cout << 1 << endl << u << endl;
return;
}
if (u > v || (v - u) % 2 == 1) {
cout << -1 << endl;
return;
}
//tdif和tu临时记录,用于后面输出答案
int dif = (v - u) / 2;
int tdif = dif / 2, tu = u;
int index = 0;//index指向二进制的当前位置
//先将dif的所有位数存好
while (dif) {
if (dif % 2)difdig[index] = 1;
else difdig[index] = 0;
index++;
dif /= 2;
}
//再将u的所有位数存好
index = 0;
while (u) {
if (u % 2)udig[index] = 1;
else udig[index] = 0;
index++;
u /= 2;
}
//对比,如果有重就输出
for (int i = 0; i < 65; i++) {
if (difdig[i] == 1 && udig[i] == 1) {
cout << 3 << endl << tu << " " << tdif << " " << tdif << endl;
return;
}
}
cout << 2 << endl << tu + tdif << " " << tdif << endl;
}
C. Match Points
时间:2024-07-08
原题:Educational Codeforces Round 64 (Rated for Div. 2) C. Match Points
题意
给正整数序列 \(Arr\) ,数字 \(z\) ,每次选两个数使差值 \(dif \ge z\) ,问最多几组数
思路
本题需要理解的较为透彻,对数字的把握比较清晰才行
首先排序是一定的,有几种思路一般,第一种是相邻的数相加,但是是错的
第二种是第一种的延伸,双指针从前往后,但是我会超时。。。
第三种二分,从第一位和二分的位置开始往后一一比对
但是当时对如何二分没有思路,现在明白了。。
就是说,假定有20个数字,此时mid=15,那么如果1到5能跟15到19完全匹配成功
说明mid大了,如果mid=10,但是在第i=8,j=18时不匹配,说明mid小了
简单理解就是这样
代码
/* 1与n-pos+1匹配,pos表示中间的起始位置 */
bool check(int pos) {
for (int i = 0; i < pos; i++) {
if (arr[n - pos + i] - arr[i] >= z)
continue;
return false;
}
return true;
}
void solve() {
cin >> n >> z;
rep(ii, 0, n) {
cin >> arr[ii];
}
sort(arr, arr + n);
int ans = 0;
int l = 0, r = n - 1;
while (l <= r) {
int mid = l + r >> 1;
//如果能匹配,将中心往右
if (check(mid)) {
l = mid + 1;
ans = mid;
}
else {
r = mid - 1;
}
}
//注意有时候mid会较大,需要判断范围
//因为答案其实是max(n-mid,mid-0) 这里的ans只是记录的mid
cout << (ans > n / 2 ? n / 2 : ans) << endl;
}
标签:Arr,07,arr,int,dif,mid,暑期,个人赛
From: https://www.cnblogs.com/lulaalu/p/18289393