CF1427E Xum 题解
学校比赛的时候考了这道题,我当然是一分没得。
这是一道好构造题。
先不说正解,我看别的题解都没有说怎么拿部分分,但是如果赛时不会正解,那么拿部分分就是很必要的一件事了,所以我在这里说一说。想直接看正解的可以跳过部分分讲解。
注:下文中的
算法一 暴力枚举 (30pts)
我们考虑在什么情况下能够合成一。因为加和运算是始终使数增加的,所以是用异或运算来合成
也就是在类似这种情况下再进行一步异或即可合成
00010110101
00010110100
可以称此局面为出解局面。
考虑如何枚举。设
关于如何判断出解局面是否出现,可以用一个
算法二 随机化 (40 \sim 96pts)
随机化还是比较好用的,我们学校
分数相对低一点的做法( 一般在
对于写数字次数不超过
分数较高一点的做法(
提高出解率的方法是构造如下的操作数列并执行:
也就是随机在操作数列里插入一些
还有一种可以获得最高
算法三 构造 (100pts)
正解其实挺简单的。考虑如何将数字
9: 0000 1001
因为题目保证给出的
考虑如何运用这个性质。观察到对于相同的数
首先另取一个数
x: 0000 1001
y: 0100 1000
之后令
x: 0000 1001
y: 0100 1000
z: 0100 0001
再令
x: 0000 1001
y: 0100 1000
z: 0100 0001
a: 1000 1001
再令
x: 0000 1001
y: 0100 1000
z: 0100 0001
a: 1000 1001
1001 0000 ←(y<<1)
b: 0001 0000
这时候发现
如此循环消掉
代码实现:
#include <iostream>
#include <bitset>
#define GMY (520&1314)
#define FBI_OPENTHEDOOR(x, y) freopen(#x ".in", "r", stdin), freopen(#y ".out", "w", stdout);
#define re register int
#define char_phi signed
#define N 100005
using namespace std;
inline void Fastio_setup(){ios::sync_with_stdio(false); cin.tie(NULL), cout.tie(NULL);}
struct Answer{int opt; long long x, y;};
long long x, y, z, a, tmp, plc, anscnt, b, c, d;
struct Answer ans[N];
#define lowbit(x) ((x) & (-(x)))
inline void Xiao(){
tmp = x; y = x;
while (tmp != 0)// 取出来x的最高位
plc = lowbit(tmp), tmp ^= plc;
while (lowbit(y) != plc)
{ans[++ anscnt] = (Answer){1, y, y}; y <<= 1;}// 得到y
// 对齐之后另其与x异或
ans[++ anscnt] = (Answer){2, x, y};
z = x ^ y;
// 另z与y相加得到a
ans[++ anscnt] = (Answer){1, y, z};
a = y + z;
// y左移
ans[++ anscnt] = (Answer){1, y, y};
d = y + y;
// a与y与x异或
ans[++ anscnt] = (Answer){2, a, d};
ans[++ anscnt] = (Answer){2, a^d, x};
b = a ^ d ^ x;
// 用b去消y
c = b>>1;
while (y != c){
if ((y & b) == b)
{ans[++ anscnt] = (Answer){2, y, b}, y = y ^ b;}
ans[++ anscnt] = (Answer){1, b, b}; b <<= 1;
}
// 此时剩下的y就是x最高位了
ans[++ anscnt] = (Answer){2, y, x};
x = x ^ y;
}
inline void work(){
cin >> x;
while (x != 1)
Xiao();
cout << anscnt << '\n';
for (re i = 1 ; i <= anscnt ; ++ i){
cout << ans[i].x;
cout << ((ans[i].opt == 1) ? (" + ") : (" ^ "));
cout << ans[i].y << '\n';
}
}
// #define IXINGMY
char_phi main(){
#ifdef IXINGMY
FBI_OPENTHEDOOR(a, a);
#endif
Fastio_setup();
work();
return GMY;
}