Codeforces Round #769 (Div. 2) 题解

A. ABC

思路

显然,一个长度大于 2 的 01 序列是不可能满足条件的。我们取其中的三个连续字符 \(a,b,c\)。按照题目条件,可得 \(a \ne b,b \ne c,a \ne c\),这显然不可能。

不过注意特判,如果序列为 1100 也不可能。

代码

#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\) 在二进制下的每一位(从高到低枚举),对于每一位:

  1. 如果 \(a'\) 的这一位为 \(0\)\(b\) 的这一位为 \(0\),那么 \(b'\) 的这一位为 \(0\)
  2. 如果 \(a'\) 的这一位为 \(0\)\(b\) 的这一位为 \(1\),那么 \(b'\) 的这一位为 \(1\)。(虽然设为 \(0\) 更优,但是 \(b'\ge b\)
  3. 如果 \(a'\) 的这一位为 \(1\)\(b\) 的这一位为 \(1\),那么 \(b'\) 的这一位为 \(1\)
  4. 如果 \(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;
}
posted @ 2022-04-21 19:00  ClapEcho233  阅读(234)  评论(0编辑  收藏  举报