目录

A. Burenka Plays with Fractions

题意:

思路:

code:

B. Interesting Sum

题意:

思路:

code:

C. Corners

题意:

思路:

code:

D1. Xor-Subsequence (easy version)

题意:

思路:

code:

D2. Xor-Subsequence (hard version)

题意:

思路:

code:


题意:

给你两个分数, 每次选其中一个的分子/分母乘上任意一个数, 问你最少几次二者能够相等.

思路:

通分判断分子即可

相同:输出0.

不同但分子间能是倍数关系, 一次即可:输出1.

不同且不是倍数关系, 需要各乘一个数达到二者的LCM才行:即需要两次输出2.

坑点:通分显然会爆int

PS:我的写法因为0不能做分母, 故需要特判.

code:

#include <bits/stdc++.h>using namespace std;
using ll = long long;void solve() {ll a, b, c, d;cin >> a >> b >> c >> d;//通分a = a * d, c = c * b;b = d = b * d;if (a == c)cout << "0\n";else if (a == 0 || c == 0)cout << "1\n";else if (a % c == 0 || c % a == 0 || a == 1 || c == 1)cout << "1\n";else   cout << "2\n";
}signed main() {ios::sync_with_stdio(false);cin.tie(nullptr);int t;cin >> t;while (t--) {solve();}    return 0;
}

B. Interesting Sum

题意:

给你一个序列, 让你选定一对, 使得:

取得最大值.

思路:

选定的l,r有四种情况可能贡献最大答案 a[l]最大a[r]最小 最大次小 次大最小 次大次小

而这四种对答案的贡献其实都是a[maxn] + a[maxn-1] + a[minn] + a[minn+1].

因此排序后直接输出即可.

code:

#include <bits/stdc++.h>using namespace std;
using ll = long long;void solve() {int n;cin >> n;vector<ll> a(n);for (int i = 0; i < n; i++) {cin >> a[i];}sort(a.begin(), a.end());cout << a[n-1] + a[n-2] - a[0] - a[1] << "\n";
}signed main() {ios::sync_with_stdio(false);cin.tie(nullptr);int t;cin >> t;while (t--) {solve();}    return 0;
}

C. Corners

题意:

给你个01矩阵, 每次选择一个一定含有至少一个1的L型的子段, 让其中的元素全部变成0, 问你最多可以操作多少次.

思路:

观察样例1, 2的区别发现. 只要构造出了一个L型的全为0的子段, 那么之后从这个子段出发每次都可以构造出一个仅包含一个1的新L子段, 使得答案最大!

那么答案就是: 矩阵中1的个数 - 构建全为0的L子段所消耗掉的1的个数(除了L本身必须要有的那个以外的另外的1的数量). PS:消耗指的是浪费掉没用上的.

消耗的1有三种情况:1)矩阵全部为1一定消耗掉2个, 2)L中的两个为1会消耗掉1个, 3)L中只有一个为1不消耗.

接下来我们找最少消耗即可. 因为L有四种形状如图:

观察发现都会包含在一个2x2的正方形中, 因此可以按照2x2的正方形遍历矩阵来找会很方便.

code:

#include <bits/stdc++.h>using namespace std;int a[505][505];
char t[505][505];void solve() {int n, m;cin >> n >> m;int cnt = 0;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {cin >> t[i][j]; a[i][j] = t[i][j] - '0';cnt += (a[i][j] == 1);}}for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {if (i + 1 <= n && j + 1 <= m && a[i][j] + a[i+1][j+1] + a[i+1][j] + a[i][j+1] <= 2) {cout << cnt << "\n";return;}}}if (cnt == n * m)cout << cnt - 2 << "\n";else   cout << cnt - 1 << "\n";
}signed main() {ios::sync_with_stdio(false);cin.tie(nullptr);int t;cin >> t;while (t--) {solve();}    return 0;
}

D1. Xor-Subsequence (easy version)

题意:

给你一个序列, 让你求出最长的满足子序列

据说题意出锅了, 但我显然没发现, 毕竟我赛时想到做法没A出来555.

思路:

我们发现D1的数据范围中每个很友好只有不到200, 异或操作如果下标i和相差超过了的二进制下的上限256的话. 接下来所有的异或都只会得到256的值.

因此我们利用这个特征, 对于每个我们最多只向前找256个就可以, 再之前的话会有不会对答案产生贡献!

updata1: 2022/8/19

很抱歉之前的解释是错误且混乱的, 浪费了读者的时间, 万分抱歉. 已经参照CF的标准答案解释等进行更正.

(将之前的 j >= max(0, i - 256), 更改为了与推导过程同步的 j >= max(0, i - 255).

updata2: 2022/8/20

修正了dp转移方程只能逆向跑的错误, 个人习惯逆向写导致口胡, orz.

1.对题目进行理解:

我们每次要进行比较的是. 但为了贴合下文操作我们将上述两个异或改写成, 其中i , j会增大( j < i), 而ai, aj 则始终 <= 200 (即二进制下不超8位).

2.设置: 

我们用dp[i]表示从第1个开始到第i个满足题目条件的最长子序列的长度. 并且我们将i, j分别称为当前状态和之前状态.

3.转移方程:

先看一个暴力的做法: 从1枚举到n, 每次先设置dp[i] = 1,因为自己一定形成一个(算是初始化?)

再令 j 从i - 1向前枚举检查是否满足, 若满足更新dp[i]为max(dp[i], dp[j] + 1).

(注意不是令j从0到i-1枚举, 这个原因和背包问题的优化的从后向前枚举是一个道理, 不做说明了)

从前向后枚举一样可以, 都会被算到, 本质上完全一致!, 只不过写法不同! (01背包优化避免重复取的才只能逆向跑)

本文下面的代码也可以正向写成

 for (int j = max(0, i - 255); j <= i - 1; j++)

4.优化 / 减少开销:

我们可以发现上面的两个异或操作实际上相当于每次只对i 或 j的二进制下的前8位进行更改, 而对前8位以外的部分不会产生影响! 原因是不超过200, 二进制下也就是不超过前8位, 异或上去后只能影响前8位, 因此我们可以借此进行优化!

下面看一个例子来解释上面这句话:ai = 200, j = 1234和 j = 2021

那既然每次只会对前八位产生影响. 那是不是证明了能够转移到当前状态i的之前状态j与i的差值一定是在这前8位的之间! 因此我们不需要从i-1枚举到0, 我们只需要枚举那些能够转移的之前状态 j 即(i - 1 ~ i - 255), 再进行的大小比较更新dp[i]即可.

5.收尾:

因此这个限制大大减少了不必要的逆向查找, 这也是我们可以用线性dp来做的真正原因, 问题就转化成了一个简单的线性dp问题, 我们扫一遍即可得到答案. 最后输出dp中最大的即可!

code:

#include <bits/stdc++.h>using namespace std;
using ll = long long;void solve() {int n;cin >> n;vector<ll> a(n);for (int i = 0; i < n; i++) {cin >> a[i];}vector<ll> dp(n);for (int i = 0; i < n; i++) {dp[i] = 1;for (int j = i - 1; j >= max(0, i - 255); j--) { if ((a[i] ^ j) > (a[j] ^ i)) { //注意加括号!dp[i] = max(dp[i], dp[j] + 1);}}}cout << *max_element(dp.begin(), dp.end()) << "\n";
}signed main() {ios::sync_with_stdio(false);cin.tie(nullptr);int t;cin >> t;while (t--) {solve();}return 0;
}

D2. Xor-Subsequence (hard version)

题意:

同上

思路:

jls用trie树 + dp做的, jls真是tql, 直接贴jls的代码了.

太优雅了写的orz.

code:

#include <bits/stdc++.h>using i64 = long long;constexpr int N = 300000 * 31;int cnt;
int trie[N][2];
int f[N][2];int newNode() {++cnt;trie[cnt][0] = trie[cnt][1] = 0;f[cnt][0] = f[cnt][1] = 0;return cnt;
}void solve() {int n;std::cin >> n;std::vector<int> a(n);for (int i = 0; i < n; i++) {std::cin >> a[i];}cnt = 0;newNode();std::vector<int> dp(n);for (int i = 0; i < n; i++) {int x = a[i] ^ i;int p = 1;for (int j = 29; j >= 0; j--) {int v = x >> j & 1;dp[i] = std::max(dp[i], f[trie[p][!v]][i >> j & 1]);p = trie[p][v];if (!p) {break;}}dp[i]++;p = 1;for (int j = 29; j >= 0; j--) {int v = x >> j & 1;if (!trie[p][v]) {trie[p][v] = newNode();}p = trie[p][v];int &res = f[p][a[i] >> j & 1];res = std::max(res, dp[i]);}}int ans = *std::max_element(dp.begin(), dp.end());std::cout << ans << "\n";
}int main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);int t;std::cin >> t;while (t--) {solve();}return 0;
}

小结

最近睡眠不规律, 21:35开始, 我21:10才起来. 开始半个小时脑子还在睡眠状态,  之后精神了些赶紧写掉了A题, B题想复杂了, 当时应该看眼榜的, 好多人3min就A掉的也就是这种类似结论题的了. 推了下结论过了, C没什么障碍, 就是写代码第一次写的又臭又长, 后来发现直接检查2x2正方形就行...

D1开始以为转化成最长上升子序列的O(NlogN)那个做法, 后来发现不太可行, 要结束了发现数据范围的意义但来不及了...

总体来看这场基本都是思维题, 码量小, 多动脑, 想通了一道题后基本直接出了没太大实现难度, 偶尔做做思维体操也挺有意思的. 也挺幸运这么慢出A和B居然还能rank不低. 第一次摆脱了灰名newbie, 成为了绿名pupil, 感觉还是要更加努力些, 多补题, 多学新东西.

今天到开学之前打算着手准备下转专业相关的事了, 下场CF估计就是在家打的最后一场了, 加油!!!

Codeforces Round #815 (Div. 2) A-D2相关推荐

  1. Codeforces Round #815 (Div. 2)

    Codeforces Round #815 (Div. 2) 传送门 :Codeforces Round #815 (Div. 2) 之前都是108键的键盘,最近在家用的68,两三天了还是非常不顺手, ...

  2. Codeforces Round #700 (Div. 2)A~D2解题报告

    Codeforces Round #700 (Div. 2)A~D2解题报告 A Yet Another String Game 原题链接 http://codeforces.com/contest/ ...

  3. Codeforces Round #700 (Div. 2) D1 D2. Painting the Array 思维

    link 题意: 给一个数组,让你从头开始选出一些数放在AAA数组中,剩下的放在BBB数组中,且是有序选择,让后把两个数组中相邻且相等的元素合并. D1: 使合并后Len(A)+Len(B)Len(A ...

  4. Codeforces Round #809 (Div. 2)。D2. Chopping Carrots (Hard Version)

    翻译: 这是这个问题的难解版本.版本之间的唯一区别是

  5. Codeforces Round #700 (Div. 2) D2 Painting the Array II(最通俗易懂的贪心策略讲解)看不懂来打我 ~

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 整场比赛的A ~ E 6题全,全部题目超高质量题解链接: Codeforces Round #700 ...

  6. Codeforces Round #730 (Div. 2) D2. RPD and Rap Sheet (Hard Version) 交互 + k进制的转换

    传送门 文章目录 题意: 思路: 题意: 定义a⊕kba\oplus_k ba⊕k​b为a,ba,ba,b在kkk进制下的不进位加法.系统会随机生成一个数xxx,你猜这个数,假设当前猜的数为yyy,如 ...

  7. Codeforces Round #602 (Div. 2) D2. Optimal Subsequences stl 黑科技

    传送门 文章目录 题意: 思路: 题意: 思路: 比较明显的是我们需要将序列从大到小排序,让后取前kkk个数,再从中选择第pospospos小的位置输出当前位置的数即可. 一开始想用setsetset ...

  8. Codeforces Round #741 (Div. 2) D2. Two Hundred Twenty One (hard version) 前缀和 + 分段模型

    传送门 文章目录 题意: 思路: 题意: 给你一个长度为nnn的串,+++代表111,−-−代表−1-1−1,让后有qqq个询问,每次询问[l,r][l,r][l,r]区间,将这段区间的数拿出来,设为 ...

  9. Codeforces Round #740 (Div. 2) D2. Up the Strip dp + 分块优化 + 逆向思维

    传送门 文章目录 题意: 思路 题意: 有nnn个细胞,你初始在第nnn细胞上,假设你当前在xxx处,你每次可以进行如下两个操作: (1)(1)(1)选择[1,x−1][1,x-1][1,x−1]内一 ...

最新文章

  1. JAVA-Eclipse快捷键
  2. 新手C#string类常用函数的学习2018.08.04
  3. python语法面试题_Python语法面试题
  4. 软件测试2019:第七次作业—— 用户体验测试
  5. zookeeper收尾+dubbo前瞻
  6. python opencv cv2.cvtColor()方法(将图像从一种颜色空间转换为另一种颜色空间)(转换成灰度图)
  7. android activity横竖屏切换,Activity重新创建问题解决!
  8. 更新和插入的并发问题_mysql经典面试题:如何读写分离?主从原理是啥?同步的延时问题...
  9. Py与Py3的区别之输入input()函数
  10. Linux开机启动过程(12):start_kernel()->还是setup_arch
  11. 隐藏画质代码_和平精英120帧率代码是什么?隐藏的120帧率代码更改方法技巧
  12. VMware Linux 共享文件夹 虚拟机无共享文件解决方法
  13. Python 语言程序设计(5-2)七段数码管程序编写设计
  14. 计算机管理创建超级用户,win10家庭版怎么开启Administrator超级管理员帐户
  15. Allegro视频教程
  16. win10系统下删除文件夹失败,提示“找不到该项目”
  17. A Feature Descriptor: Shape Context
  18. 利用python核算工资_年薪10w用Python,年薪50w利用Python
  19. 安徽省淮南市谷歌卫星地图下载
  20. 墨尔本python培训班_墨的解释|墨的意思|汉典“墨”字的基本解释

热门文章

  1. PSIFT:Pore Scale-invariant feature transform;毛孔尺度不变特征点
  2. 区块链 以太坊 多层调用,获取调用者 msg.sender
  3. android中Zing二维码扫描,二维码生成
  4. 【软件相关】Eagle软件入门教程
  5. linux 杂项设备,浅谈 MISC杂项设备
  6. 【蓝桥杯大赛】简单回忆一下我的蓝桥杯比赛历程
  7. bzoj1050: [HAOI2006]旅行comf
  8. 【程序设计训练】棋盘
  9. 30岁选择回乡创业的90后告诉你,加盟汉庭酒店怎么样?
  10. java滑杆和进度条_HTML5实现自带进度条和滑块滑杆效果