Problem - B - Codeforces
这题看了好久,一直没思路..也可能是早上来没睡醒的原因吧.有点困..
昨天晚上12点睡的,然后早上直接睡到7.48....真的6啊
话说这题真有点猜的成分,
先说我的思路:一开始和的奇偶
如果为偶数:那么分的所有部分的和一定都为偶数才有利
如果为奇数:那么分的所有部分的和一定为奇数才对答案有利
但是这个奇数和和偶数和非常难找....
(蚌埠住了...今天出了百度之星成绩极其的拉跨.....感觉比赛的时候感觉自己啥也不会....我是菜鸡..,感觉自己还是有实力的,但就是自己暑假集训的状态极其的差啊!!!)
正解:
要使分裂的部分的最大公约数最大,分裂的部分一定为2个
证明如下:
设如果k大于2的话,答案为ans=gcd(b1,b2,b3...bk),因为b1和b2一定为ans的倍数,并且a1+a2也一定为ans的倍数且不会使答案更坏
所以gcd(b1+b2,b3,b4,bk)一定优于gcd(b1,b2,b3,b4,bk)
Contest Login
昨天航电的一道博弈论题目 ,昨天做的时候就感觉没有啥思路...今天也没啥思路..队内大腿队友还是强啊!!
正解:设现在x先手
1.如果两边都为!x,那么x输
2.如果两边为!x和x,那么x只能选x,x不具有主动权,两者向内推进
3.如果两边为x和x,那么x可以选任意一边,!x只能跟着x操作,即x具有主动权,可以发现x胜利的话,必须至少有2个连续的x,还有我们需要特判下出现2个!x!x的情况(此情况可能是平局!!)比如字符串为010101101010,从左到右的话,0在7位置受阻,从右到左的话,0在6位置受阻,此时为平局!!
#include
#include
#include
using namespace std;
const int N = 1e6 + 2;
int t, n, l, r, now;
char s[N];
void firstchk() {
while(l < r && s[l] != s[r]) {
if(s[l] == now)
l++;
else
r--;
now ^= 1;
}
if(l == r && s[l] == now)
l++;
}
int chkl(int n) {
for (int i = l; i <= r; i++) {
if(n != s[i])
return i;
n ^= 1;
}
return -1;
}
int chkr(int n) {
for (int i = r; i >= l; i--) {
if(n != s[i])
return i;
n^= 1;
}
return -1;
}
int main() {
scanf("%d", &t);
while(t--) {
now = 0;
scanf("%d%s", &n, s + 1);
for (int i = 1; i <= n; i++){
s[i] = s[i]&1;
}
l = 1, r = n;
firstchk();
if(l > r) {
puts("-1");
continue;
}
if(s[l] != now) {
printf("%d\n", now ^ 1);
continue;
}
int lpos = chkl(now);
int rpos = chkr(now);
if(lpos != -1 && s[lpos] == now || rpos != -1 && s[rpos] == now)
printf("%d\n", now);
else if(rpos + 1 == lpos || lpos == -1)
puts("-1");
else
printf("%d\n", s[lpos]);
}
return 0;
}
这个好像将0和1的字符可以直接和(0和1)比较
for (int i = 1; i <= n; i++){
s[i] = s[i]&1;
}
今天下午又刷了一套小白月赛的题目,感觉题目质量还是很高的!
登录—专业IT笔试面试备考平台_牛客网
这题直接set+二分就出来了,但是tm的题目有毒啊!!
必须关闭网络流并且不能用endl!!不然我早就过了!!
登录—专业IT笔试面试备考平台_牛客网
一道博弈论的题目...比赛时候没有做出来,自己太菜了....
比赛结束后一共过了500多个人....
感觉还是自己太菜了....
比赛的时候没太有思路,就开始乱想了....
看了题解感觉确实牛..
考察点:思维,博弈,对称策略(模拟棋)
1.给带的a,b2个数,如果a,b的最小值模3==0,那么后手赢
证明如下:
假设给定 9 11,无论先手怎样操作,后手都可以根据先手下模拟棋子,
将其变为6 8,然后循环,最后先手得到0 2,先手输
2.如果a,b的最小值模3!=0,如果模数为1,并且a==b,那么后手赢
证明如下:
给定 10 10,设最小值为第一位,第一轮先手 9 8,(此时最小值位置发生改变)第二轮后手可以将其变成 8 6,然后再根据先手下模拟棋,
后手赢
3.其他情况先手赢
证明(a=b&&min(a,b)%3==2)先手赢
证明如下:
给定11 11,第一轮操作为 9 10,后手无论如何也不能改变最小值的位置
然后先手可以根据后手下模拟棋
所以先手赢
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
登录—专业IT笔试面试备考平台_牛客网
一道感觉比较难的构造吧...
我想了想,没有想到如何分块的方法..
比如54321 987 10 11 12 13 14
然后看了题解感觉挺简单的...
我们设f[x]为x对x-1 x-2 x-3 x-4 3 2 1 的贡献,显而易见f[x]=log2(x-1)+1
然后我们就可以我们可以以O(n)统计每一个的f[i],如果总的f[i]和 ,现在就是k 答案是一定的..(贪心) 我们可以构造下降+上升的一段 比如7 6 5 3 1 2 4,这一段的贡献总和为f[7]+f[6]+f[5]+f[3] 如果当前的f[i]<=k我们就然k-f[i]for(int i=n;i>=1;i--){
if(f[i]<=k){
a.push_back(i);
k=k-f[i];
}else{
b.push_back(i);
}
}
#include