1007 cats 的 k-xor
由于是不进位相加,所以一定满足 。因此有
时,没有进制满足要求。
时,说明原本的加法就不需要进位,有无限个 k 满足要求。
时,这是由于加法没有进位导致的,而且 k 一定是 a + b - c 的因数。枚举 a + b - c的因数,判断该因数是否为满足条件的进制。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int t;
inline int read() {
int x = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
bool check(int a, int b, int c, int k) {
while (a || b || c) {
int aa = a % k, bb = b % k, cc = c % k;
if ((aa + bb) % k != cc) return false;
a /= k, b /= k, c /= k;
}
return true;
}
signed main() {
t = read();
int a, b, c;
while (t--) {
int ans = 0LL;
a = read(), b = read(), c = read();
if (a + b == c) { puts("-1"); continue; }
if (a + b < c) { puts("0"); continue; }
int tar = a + b - c;
for (int i = 1; i * i <= tar; i++) {
if (tar % i == 0) {
if (i >= 2 && check(a, b, c, i)) ans++;
if (i * i < tar && tar / i >= 2 && check(a, b, c, tar / i)) ans++;
}
}
printf("%lld\n", ans);
}
return 0;
}
1012 cats 的电脑中毒
对于任意字符串 ,记录任意两个串之间对应位不同的位数,记最大的数为 num,答案为
。
证明:
- 由于字符串的顺序不影响结果,假设
与
相差的位数最多,总共 num 位不同,n - num 位相同,那么在只考虑这两个字符串的情况下总共需要
步。
- 此时最难变成的字符串 tar 为,当
的时候,该字符串对应位置上字符与这两个字符串对应字符不同;剩余位置上的字符,当 num 为偶数时,一半跟字符串
对应位置字符相同,另一半与
对应位置上的字符相同;当 num 为奇数时,
位跟
对应位置字符相同,
位跟
对应位置上的字符相同(反过来也一样)。
- 由于
与
跟 tar 最多有
位相同,所以需要
步(num为偶数时,加一后除 2 结果不受影响)
- 由于字符串的顺序不影响结果,假设
与字符串 tar 相差位数最少,总共相差
位。
- 此时再考虑字符串
,结果一定不会比
更劣。假设
与
字符串有 cnt 位不同,那么一定有
。同理,再只考虑
与
的情况下,
与
总共需要
步。(只考虑
与
同理)。
- 从
变成字符串 tar 步骤一定多与由
变得(通过样例观察得出,不太会证明)。
由此,可以得出 。
#include <bits/stdc++.h>
using namespace std;
int dif(string x, string y) {
int num = 0;
for (int i = 0; i < x.size(); i++) {
if (x[i] != y[i]) num++;
}
return num;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int t, n;
string a, b, c;
cin >> t;
while (t--) {
cin >> n;
cin >> a >> b >> c;
int num = dif(a, b);
num = max(num, dif(b, c));
num = max(num, dif(a, c));
cout << n - (num + 1) / 2 << '\n';
}
return 0;
}