CF1615C-Menorah
题目大意:给出一个全由0与1组成的数列a,每次操作可以选择一个值为1的元素,让这个元素的值保持不变,其它元素取异或。给出一个数列b,问是否可以将数列a变成数列b,如果可以,输出最少需要的操作次数。
注意到:对一个元素x进行操作之后紧接着对另一个元素y进行操作,结果就是交换了x和y的值,数列中其它数保持不变。结果实际上就是经过这些交换得到的。判断需要从0变成1的数的数量是否等于需要从1变成0的数的数量就可以了。
在开始交换前,可以先取一个保持为1不变的元素,对它进行一次操作,将整个数列反转一遍,判断翻转后的数列中需要从0变成1的数的数量是否等于需要从1变成0的数的数量,即原数列中需要保持1不变的数的数量减去1之后和保持0不变的数的数量是否相等。应该比较两种方法所需操作次数,取较小的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include <bits/stdc++.h> using namespace std; int sum[2][2]; char a[100005], b[100005]; int main() { int n, i, _, res; scanf("%d", &_); while (_--) { scanf("%d%s%s", &n, a + 1, b + 1); memset(sum, 0, sizeof(sum)); for (i = 1; i <= n; i++) sum[a[i] - '0'][b[i] - '0']++; if (sum[0][1] != sum[1][0] && sum[1][1] - sum[0][0] != 1) printf("-1\n"); else { res = 1e9; if (sum[0][1] == sum[1][0]) res = sum[0][1] * 2; if (sum[1][1] - sum[0][0] == 1) res = min(res, 1 + sum[0][0] * 2); printf("%d\n", res); } } return 0; }
|