1.26-2.04题解
https://codeforces.com/contest/1900/problem/C

一道简单的树形DP 就是题目需要读懂 他那个l r u是string的编号
然后我们可以在dfs里面加一个参数step走到叶子节点就比较下 比较简单
void dfs(int u, int fa, int step) {
if (a[u].l == 0 && a[u].r == 0) {
ans = min(ans, step);
return ;
}
if (a[u].l) {
if (s[u - 1] != 'L')
dfs(a[u].l, u, step + 1);
else dfs(a[u].l, u, step);
}
if (a[u].r) {
if (s[u - 1] != 'R')
dfs(a[u].r, u, step + 1);
else dfs(a[u].r, u, step);
}
}
https://codeforces.com/contest/1898/problem/B

很好的一道题 首先这个题倒着做 然后就是怎么拆分了 肯定是一直拆下去直到最大拆分小于等于他即可 那么拆分的次数是多少次呢 是 Ai/Ai+1上取整 得到k个数 就是k-1步
我当时做这个就被这个搞了很久 我不知道得到k个数k-1步 我只是模拟
10 3
10 2 两个样例 10 3 ->4 10 2 -> 5 我以为整除的就要多减去1 因为10 2 确实只要4步
那么 10 3 =3 我以为要加 1 其实没必要搞这么复杂 就是一个向上取整 所以很多时候
碰到这个奇数偶数相除有余数或没余数情况 思考下有没有可能只要一个向上取整就能统统解释清楚了 (或者一个向下)
https://codeforces.com/contest/1894/problem/C

这个题 我当时做的时候就想了很久了
现在回头看我代码 也是看来好一会才明白自己的思路
说个题外话 我大号最近上的分被检测出开小号 代码重复了 分白上了 真的是草了。我不管 cf现在欠我124分
说下这个题
我当初发现每次操作原数列最后一个数就行
因为这样肯定是最好的 如果操作的过程中出现重复了
那么肯定是可以的 因为可以通过环回来
如果操作次数>=k也是可以的
然后讲下now 和 x是什么意思
now表示总共左移的位移量 x是此时最后那个数的下标
now注意要取模
我们令now初始为an 即可 然后不断模拟即可 此题还是很有意思的
now = a[n];
if (a[n] > n) {
cout << "NO" << endl;
return ;
}
bool flag=0;
while (1) {
if(ans>2*n)break;
int x = n - now;
if (s.count(x) ) {
ans++;
flag=1;
break;
}
s.insert(x);
ans++;
if(ans>=k){
cout<<"YES"<<endl;return ;
}
if(a[x]>n){
cout<<"NO"<<endl;return ;
}
now = (now + a[x]) % n;
if(now==0)now=n;
if (now == n) {
flag=1;
break;
}
https://codeforces.com/contest/1891/problem/B

这是个好题 同时也是一个阅读理解题
这个修改 是按顺序来的
讲下什么时候不能修改
如果他要%(1<<j) 那么他就在20-2J-1是没有数的 否则不可能可以被整除 由此我们可以求得他最多被整除的位数就是j-1 由此j-1以下的数字我都是可以整除的 被整除后就需要把他下一次整除的位置修改下 由于加了2^bj-1 所以他只好从bj-1开始了
void swa(queue<int>&q) {
queue<int>temp;
swap(temp, q);
}
void solve(int t) {
cin >> n >> m;
for (int i = 0; i <= 30; i++) {
swa(q[i]);
}
for (int i = 1; i <= n; i++) {
cin >> a[i];
// for (int j = 30; j >= 0; j--) {
// if (a[i] & (1 << j)) {
// q[j].push(i);
// break;
// }
// }应该是找最小的那个 因为比他大了不能整除
for (int j = 1; j <= 30; j++) {
//不用从0开始 没有意义 因为题目没给0 是1-30 最少是 2
// if (a[i] & (1 << j)) {
//不能这样写 因为 比如3 这样的 也会被认为能整除
//如果讨论的是能不能整除 应该是%
if (a[i] % (1 << j)) {
q[j - 1].push(i);
//意味着此时1<<j大于你了 %的余数位ai
// cout<<i<<" "<<j-1<<endl;
break;
}
}
}
for (int i = 1; i <= m; i++)cin >> b[i];
//最多操作30次
for (int j = 1; j <= m; j++) {
for (int i = 30; i >= 1; i--) {
//注意细节 i大于等于1
int w = qpow(2, i);
int ww = qpow(2, b[j]);
if (w % ww)break;
if(q[i].size()==0)continue;
// cout<<j<<" "<<i<<endl;
while (q[i].size()) {
int u = q[i].front();
q[i].pop();
a[u] += ww/ 2;
q[b[j] - 1].push(u);
}
}
}

浙公网安备 33010602011771号