题目大意:
给出一个偶数n,接下来输入两个长度为n的01串,在第一个字符串中,1表示编号为 i 的人可以表演小丑,而0表示不可以。在第二个字符串中,1表示编号为 i 的人可以表演杂技,0则表示不可以。一共有两次表演,有以下几条要求:
- 每个人只能参与一场表演
- 每次表演的人数必须等于n / 2
- 第一次表演小丑的人数必须和第二次表演杂技的人数相同
要求找出表演方案,如果能找到,则输出参加第一次表演的演员编号,如果找不到方案则输出 - 1。
解题思路:
假设00 为A, 01 为B 11 为C, 10 为D,而我们对应选择的为a b c d,则可以根据题意构造方程:
- a + b + c + d = n / 2
- c + d = B - b + D - d
根据方程推出:d = B + D - n / 2 + a
我们可以枚举a,从而确定 d 的个数,然后判断d是否在合法的范围内,紧接着枚举 c 的个数,b的个数再拿n / 2去减就可以了。然后判一下b是否合法,如果合法则停止枚举,输出该方案,如果都枚举完了没有得到结果则输出-1,我这里用i j k l表示的 a b c d 用c1 c2 c3 c4表示的总数ABCD。
Code:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
const int mod = 1e9 + 7;
const int N = 1e6;
const int inf = 0x3f3f3f3f;
typedef long long ll;
int c1, c2, c3, c4;
int n;
string a, b;
int main()
{
cin >> n >> a >> b;
for (int i = 0; i < n; i ++)
{
if (a[i] == '0' && b[i] == '0')
c1++;
else if (a[i] == '0' && b[i] == '1')
c2++;
else if (a[i] == '1' && b[i] == '0')
c3++;
else if (a[i] == '1' && b[i] == '1')
c4++;
}
bool ok = false;
int ans1, ans2, ans3, ans4;
for (int i = 0; i <= c1 && i <= n / 2; i ++)//先枚举a
{
int j = i + c2 + c4 - n / 2;//算出d以后判断范围
if (j < 0 || j > c4 || j > n / 2) continue;
for (int k = 0; k <= c3 && k <= n / 2; k ++)//再枚举c
{
int l = n / 2 - i - j - k;//算出b以后再判范围
if (l >= 0 && l <= c2 && l <= n / 2)
{
ans1 = i, ans2 = l, ans3 = k, ans4 = j;//对应的a b c d
ok = true;
break;
}
}
if (ok) break;
}
if (!ok)
cout << -1 << endl;
else
{
for (int i = 0; i < n; i ++)
{
if (a[i] == '0' && b[i] == '0' && ans1)
cout << i + 1 << ' ', ans1--;
else if (a[i] == '0' && b[i] == '1' && ans2)
cout << i + 1 << ' ', ans2--;
else if (a[i] == '1' && b[i] == '0' && ans3)
cout << i + 1 << ' ', ans3--;
else if (a[i] == '1' && b[i] == '1' && ans4)
cout << i + 1 << ' ', ans4--;
}
cout << endl;
}
return 0;
}