补题链接:Here

1527A. And Then There Were K

题目大意:

给一个正整数n,求最大的k,使得 \(n \& (n−1) \& (n−2) \& (n−3) \& … (k) = 0\)

思路:

就假设 \(n\) 为 17,二进制为 10001,我们来模拟一下求解过程。

17 10001

16 10000

15 01111

因为按位与的特点就是,一位上只要有一个0,这一位最后就是0。

我们竖着来看,17到15,每一位上就都出现过一次0了,所以15就是答案。然后举更多例子观察特点,发现,答案就是让n的二进制最左边的1置为0,后面全置为1。

如:

10001 11101 10111的答案都是 01111

【AC代码】

int qpow(int a, int b) {int ans = 1; while (b) {if (b & 1)ans = ans * a; b >>= 1; a = a * a;} return ans;}
void solve() {
int n;
cin >> n;
int ans = 0;
while (n) {
n >>= 1;
++ans;
}
cout << qpow(2, ans - 1) - 1 << "\n";
}

转化思维,模拟上面的过程

void solve() {
ll n, k = 0;
cin >> n;
while (k * 2 + 1 < n)k = k * 2 + 1;
cout << k << "\n";
}

遇到这种位运算的题目,一般都是把数的二进制表示出来,然后根据运算的特点(比如&的特点就是,只要有一个0,最后就是0),找规律。

1527B1. Palindrome Game (easy version)

题目大意:

给一个字符串(这题的字符串一开始一定是一个回文)。

1.可以把一个0变为1,操作者的数字+1。

2.或者翻转整个字符串(前提是该字符串不是回文且上一个人的操作不是翻转)。

Alice先,最后字符串全为1时,谁的数字大谁输,相同则平局。

思路:

因为一开始就是回文,所以Alice只好进行1操作,如果可以在这个操作之后仍然让它时一个回文,那Alice就赢定了。

比如:10001

Alice进行1之后,10101

Bob没法翻转,只好进行1操作,11101

这时,Alice很聪明,不会傻傻地让自己的数字变大,选择2翻转字符串,10111

Bob只好继续1操作,111111

这时Bob都已经数字为2了,Alice为1,所以Alice胜

比如:10101

Alice 1操作之后并不是回文,这就让Bob有机可乘,最后是Bob赢了

关键在于,Alice第一次操作之后它还是不是回文,而这取决于改字符串中间的字符是不是0,只有中间的字符是0,且字符串长为奇数(偶数的话连中间都没有)的时候Alice赢,否则Bob赢。

还有一个特殊情况,就是只有一个0的时候,因为刚开始就是回文,Alice只好1操作,所以Alice必定+1,而Bob是0,所以Bob赢了。

void solve() {
int n; string s;
cin >> n >> s;
int cnt0 = count(s.begin(), s.end(), '0');
if (cnt0 == 1)cout << "BOB\n";//只有一个0
else if (n & 1 and s[n / 2] == '0')cout << "ALICE\n";//是奇数个,中间为0
else cout << "BOB\n";
}

压缩判断条件:奇数个0 并且不为 1 个,此时一定是 Alice 获胜了

void solve() {
int n; string s;
cin >> n >> s;
int k = count(s.begin(), s.end(), '0');
if (k & 1 and k != 1)cout << "ALICE\n";
else cout << "BOB\n";
}

1527B2. Palindrome Game (hard version)

题目大意:

这题跟B1的区别就是,一开始的字符串可能不是回文。

思路:

一开始是回文时,用B1的结论。

一开始不是回文时,Alice就可以一开始就翻转,让Bob喘不过气来,所以Bob不可能赢。

但是有一种平局的情况,001,只有2个0,且中间是0。

void solve() {
int n; string s;
cin >> n >> s;
int k = count(s.begin(), s.end(), '0');
string b = s;
reverse(b.begin(), b.end());
if (b == s) { // 用 1 的结论
if (k == 1 || !(n & 1))cout << "BOB\n";
else if ((n & 1) and s[n / 2] == '0')cout << "ALICE\n";
else cout << "BOB\n";
} else {
if (k == 2 and (n & 1) and s[n / 2] == '0')
cout << "DRAW\n";
else cout << "ALICE\n";
}
}

赛后 DP 写法:很复杂,不推荐

const int N = 1010;
int dp[N][N][2][2];
int vis[N][N][2][2];
int DP(int a, int b, int c, int d) {
if (vis[a][b][c][d])return dp[a][b][c][d];
vis[a][b][c][d] = 1;
int &tmp = dp[a][b][c][d] = N;
if (a + b + c == 0) tmp = 0;
if (b and d) tmp = min(tmp, -DP(a, b, c, 0));
if (a) tmp = min(tmp, -DP(a - 1, b + 1, c, 1) + 1);
if (b) tmp = min(tmp, -DP(a, b - 1, c, 1) + 1);
if (c) tmp = min(tmp, -DP(a, b, c - 1, 1) + 1);
return tmp;
}
void solve() {
int n; string s;
cin >> n >> s;
int a = 0, b = 0, c = 0;
for (int i = 0; i * 2 + 1 < n; ++i) {
if (s[i] == '0' and s[n - i - 1] == '0')a++;
if (s[i] != s[n - 1 - i]) b++;
}
if (n & 1 and s[n / 2] == '0')c = 1;
int ans = DP(a, b, c, 1);
if (ans > 0)cout << "BOB\n";
else if (ans == 0)cout << "DRAW\n";
else cout << "ALICE\n";
}

1527C. Sequence Pair Weight

题目大意:

给一个数组,求每个子序列的一对相同数字的数量之和。

分析:

暴力 \(\mathcal{O}(n^2)\),肯定不行,所以肯定有什么 \(\mathcal{O}(n)\) 的方法可以实现。

首先,答案肯定跟这些数字出现的次数有关,其次,也跟数字所在的位置有关。

所以很容易想到用 map 去存储位置并计数

void solve() {
map<int, ll>mp;
ll ans = 0;
int n;
cin >> n;
for (int i = 1, a; i <= n; ++i) {
cin >> a;
ans += mp[a] * (n - i + 1);
mp[a] += i;
}
cout << ans << "\n";
}

Codeforces Round #721 (Div. 2) AB思维,B2博弈,C题map的更多相关文章

  1. Codeforces Round #721 (Div. 2)A. And Then There Were K(位运算,二进制) B1. Palindrome Game (easy version)(博弈论)

    半个月没看cf 手生了很多(手动大哭) Problem - A - Codeforces 题意 给定数字n, 求出最大数字k, 使得  n & (n−1) & (n−2) & ...

  2. Codeforces Round #713 (Div. 3)AB题

    Codeforces Round #713 (Div. 3) Editorial 记录一下自己写的前二题本人比较菜 A. Spy Detected! You are given an array a ...

  3. Codeforces Round #298 (Div. 2) A、B、C题

    题目链接:Codeforces Round #298 (Div. 2) A. Exam An exam for n students will take place in a long and nar ...

  4. Codeforces Round #297 (Div. 2)A. Vitaliy and Pie 水题

    Codeforces Round #297 (Div. 2)A. Vitaliy and Pie Time Limit: 2 Sec  Memory Limit: 256 MBSubmit: xxx  ...

  5. 【CF1256】Codeforces Round #598 (Div. 3) 【思维+贪心+DP】

    https://codeforces.com/contest/1256 A:Payment Without Change[思维] 题意:给你a个价值n的物品和b个价值1的物品,问是否存在取物方案使得价 ...

  6. Codeforces Round #260 (Div. 2)AB

    http://codeforces.com/contest/456/problem/A A. Laptops time limit per test 1 second memory limit per ...

  7. Codeforces Round #259 (Div. 2)AB

    链接:http://codeforces.com/contest/454/problem/A A. Little Pony and Crystal Mine time limit per test 1 ...

  8. Codeforces Round #143 (Div. 2) (ABCD 思维场)

    题目连链接:http://codeforces.com/contest/231 A. Team time limit per test:2 seconds memory limit per test: ...

  9. Codeforces Round #395 (Div. 2)(A.思维,B,水)

    A. Taymyr is calling you time limit per test:1 second memory limit per test:256 megabytes input:stan ...

  10. Codeforces Round #416 (Div. 2)(A,思维题,暴力,B,思维题,暴力)

    A. Vladik and Courtesy time limit per test:2 seconds memory limit per test:256 megabytes input:stand ...

随机推荐

  1. Flutter搭建

    目录 下载 Flutter SDK 配置 Flutter 环境变量及镜像 检查开发环境 参考 下载 Flutter SDK flutter官网下载:https://flutter.io/sdk-arc ...

  2. C/C++ 通过SQLiteSDK增删改查

    SQLite,作为一款嵌入式关系型数据库管理系统,一直以其轻量级.零配置以及跨平台等特性而备受青睐.不同于传统的数据库系统,SQLite是一个库,直接与应用程序一同编译和链接,无需单独的数据库服务器进 ...

  3. [ABC261E] Many Operations

    Problem Statement We have a variable \(X\) and \(N\) kinds of operations that change the value of \( ...

  4. 好家伙,这个开源项目硬生生复制了一个 ChatGPT Plus 出来

    最近有一款聊天机器人框架 Lobe Chat 火出了天际,它不仅支持多模态,支持语音会话,还有一个强大的 Function Calling 插件生态系统(可以作为 ChatGPT 插件的平替).最重要 ...

  5. 小傅哥自研插件,为开发提效80%,已经有8.1k安装量!

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 哈喽,大家好我是技术UP主小傅哥. 如果你担心维护成本和性能考量,不想使用 BeanUtils ...

  6. Selenium等待元素出现

    https://www.selenium.dev/documentation/webdriver/waits/ 有时候我们需要等待网页上的元素出现后才能操作.selenium中可以使用以下几种方法等大 ...

  7. Springboot快速集成阿里云RocketMq

    前言 随着互联网的兴起,越来越多的用户开始享受科技带来的便利,对于服务的压力也日益增大,随即便有了高并发.高性能.高可用等各种解决方案,这里主要介绍RocketMq的集成方法.(文末附源码地址) 正文 ...

  8. python tkinter 使用(六)

    python tkinter 使用(六) 本文主要讲述tkinter中进度条的使用. 1:确定的进度条 progressbar = tkinter.ttk.Progressbar(root, mode ...

  9. 【李南江】从零玩转TypeScript

    前言 老套路肯定是 需要知道TS是干啥用的啦. 1.什么是TypeScript(TS)? TypeScript简称TS TS和JS之间的关系其实就是Less/Sass和CSS之间的关系 就像Less/ ...

  10. 11 个步骤完美排查Linux服务器是否被入侵

    文章来源公众号:LemonSec 随着开源产品的越来越盛行,作为一个Linux运维工程师,能够清晰地鉴别异常机器是否已经被入侵了显得至关重要,个人结合自己的工作经历,整理了几种常见的机器被黑情况供参考 ...