Codeforces Round #769 (Div. 2) 题解
A. ABC
思路
显然,一个长度大于 2 的 01
序列是不可能满足条件的。我们取其中的三个连续字符 \(a,b,c\)。按照题目条件,可得 \(a \ne b,b \ne c,a \ne c\),这显然不可能。
不过注意特判,如果序列为 11
或 00
也不可能。
代码
#include <bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define I inline
#define ll long long
#define Con const
#define CI Con int
#define RI register int
#define W while
#define gc getchar
#define D isdigit(c=gc())
#define pc(c) putchar((c))
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define Gmax(x,y) (x<(y)&&(x=(y)))
#define Gmin(x,y) (x>(y)&&(x=(y)))
#define ms(a,x) memset((a),(x),sizeof(a))
using namespace std;
namespace FastIO
{
CI FS = 1e5; int Top = 0; char S[FS];
I void readc (char& c) {W (isspace (c = gc ()));}
Tp I void read (Ty& x) {char c; int f = 1; x = 0; W (! D) f = c ^ '-' ? 1 : -1; W (x = (x * 10) + (c ^ 48), D); x *= f;}
Ts I void read (Ty& x, Ar&... y) {read (x); read (y...);}
Tp I void write (Ty x) {x < 0 && (pc ('-'), x = -x, 0); W (S[++ Top] = x % 10 + '0', x /= 10); W (Top) pc (S[Top --]);}
Tp I void writeln (Ty x) {write (x); pc ('\n');}
} using namespace FastIO;
int t, n; string s;
int main () {
read (t); W (t --) {
read (n); getline (cin, s);
if (n > 2) printf ("NO\n");
else if (n == 2 && (s == "11" || s == "00")) printf ("NO\n");
else printf ("YES\n");
}
return 0;
}
B. Roof Construction
思路
首先,设 \(k\) 满足 \(2^k\le n-1\le 2^{k+1}\),由于从 \(0 \sim n - 1\) 中 \(\ge 2^k\) 的数肯定小于等于 \(<2^k\) 的数,所以必然有一个 \(<2^k\) 的数在 \(\ge2^k\) 的数的旁边,于是贡献就必然 \(\ge2^k\) 。考虑怎么使最小答案等于 \(2^k\)。
显然,把 \(\ge2^k\) 的数和 \(<2^k\) 的数分别放在一起,交界处为 \(0,2^k\) 即可
\[2^k+1,2^k+2,\cdots,n-1,2^k,0,1,2,\cdots,2^k-1
\]
代码
#include <bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define I inline
#define ll long long
#define Con const
#define CI Con int
#define RI register int
#define W while
#define gc getchar
#define D isdigit(c=gc())
#define pc(c) putchar((c))
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define Gmax(x,y) (x<(y)&&(x=(y)))
#define Gmin(x,y) (x>(y)&&(x=(y)))
#define ms(a,x) memset((a),(x),sizeof(a))
using namespace std;
namespace FastIO
{
CI FS = 1e5; int Top = 0; char S[FS];
I void readc (char& c) {W (isspace (c = gc ()));}
Tp I void read (Ty& x) {char c; int f = 1; x = 0; W (! D) f = c ^ '-' ? 1 : -1; W (x = (x * 10) + (c ^ 48), D); x *= f;}
Ts I void read (Ty& x, Ar&... y) {read (x); read (y...);}
Tp I void write (Ty x) {x < 0 && (pc ('-'), x = -x, 0); W (S[++ Top] = x % 10 + '0', x /= 10); W (Top) pc (S[Top --]);}
Tp I void writeln (Ty x) {write (x); pc ('\n');}
} using namespace FastIO;
int T, n;
int main () {
RI i, j; read (T); W (T --) {
read (n); int k = 0; W (1 << (k + 1) <= n - 1) ++ k; for (i = (1 << k) + 1; i <= n - 1; ++ i) printf ("%d ", i);
printf ("%d ", (1 << k)); for (i = 0; i <= (1 << k) - 1; ++ i) printf ("%d ", i); printf ("\n");
}
return 0;
}
C. Strange Test
思路
如果没有第三个操作,那么答案显然为 \(b-a\)。
设 \(a\) 经过若干次操作后为 \(a'\),\(b\) 经过若干次操作后为 \(b'\)。那么答案就是 \((a'-a)+(b'-a)+((a'|b')-b')+1\),化简后为 \((1-a-b)+a'+(a'|b')\)。\((1-a-b)\) 是常数,于是我们就要让 \(a'+(a'|b')\) 最小。
因为 \(a<b\),所以 \(a'\) 的范围为 \(a\sim b\)。接下来,我们需要通过 \(a'\) 和 \(b\) 来构造出一个最佳的 \(b'\)。先使 \(b'=0\),我们枚举 \(b\) 在二进制下的每一位(从高到低枚举),对于每一位:
- 如果 \(a'\) 的这一位为 \(0\),\(b\) 的这一位为 \(0\),那么 \(b'\) 的这一位为 \(0\)。
- 如果 \(a'\) 的这一位为 \(0\),\(b\) 的这一位为 \(1\),那么 \(b'\) 的这一位为 \(1\)。(虽然设为 \(0\) 更优,但是 \(b'\ge b\))
- 如果 \(a'\) 的这一位为 \(1\),\(b\) 的这一位为 \(1\),那么 \(b'\) 的这一位为 \(1\)。
- 如果 \(a'\) 的这一位为 \(1\),\(b\) 的这一位为 \(0\),那么 \(b'\) 的这一位为 \(1\),且退出枚举。(因为从高到低枚举,所以此时 \(b'\) 肯定比 \(b\) 大了,后面的全部为 \(0\) 即可)
最后答案就是 \(\min(b-a,(1-a-b)+\min\limits_{a'=a}^b(a'+(a'+b')))\)。
代码
#include <bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define I inline
#define ll long long
#define Con const
#define CI Con int
#define RI register int
#define W while
#define gc getchar
#define D isdigit(c=gc())
#define pc(c) putchar((c))
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define Gmax(x,y) (x<(y)&&(x=(y)))
#define Gmin(x,y) (x>(y)&&(x=(y)))
#define ms(a,x) memset((a),(x),sizeof(a))
using namespace std;
namespace FastIO
{
CI FS = 1e5; int Top = 0; char S[FS];
I void readc (char& c) {W (isspace (c = gc ()));}
Tp I void read (Ty& x) {char c; int f = 1; x = 0; W (! D) f = c ^ '-' ? 1 : -1; W (x = (x * 10) + (c ^ 48), D); x *= f;}
Ts I void read (Ty& x, Ar&... y) {read (x); read (y...);}
Tp I void write (Ty x) {x < 0 && (pc ('-'), x = -x, 0); W (S[++ Top] = x % 10 + '0', x /= 10); W (Top) pc (S[Top --]);}
Tp I void writeln (Ty x) {write (x); pc ('\n');}
} using namespace FastIO;
int T, a, b;
int main () {
RI i, j; read (T); W (T --) {
read (a, b); int ans = (1 - a - b);
int minn = 0x7fffffff;
int aa, bb = 0; for (aa = a; aa <= b; ++ aa) {
bb = 0;
for (i = 21; i >= 0; -- i) {
if (((aa >> i) & 1) && ((b >> i) & 1)) bb = bb | (1 << i);
if (! ((aa >> i) & 1) && ((b >> i) & 1)) bb = bb | (1 << i);
if (((aa >> i) & 1) && ! ((b >> i) & 1)) {bb = bb | (1 << i); break;}
}
minn = min (minn, ans + aa + (aa | bb));
}
printf ("%d\n", min (minn, b - a));
}
return 0;
}