Codeferce 1138B - Circus
题目的意思是给定两个01序列
第一个序列中如果a[i]为1,表示第i个人可以表演clown,0表示不能表演clown。
第二个序列中如果c[i]为1,表示第i个人可以表演acrobat,0表示不能表演acrobat。
总共两次表演,每次出场n/2个人,且满足表演过的不能再次出场,且第一次出场的可以表演clown的人的数量的必须等于第二次出场表演acrobat。
输出第一次出场的人的编号,无解输出-1
当时想了一会,没想出来,我越想越乱,看了题解后顿时明白了,题解也算是一种暴力吧
这其实就是一个解方程的过程,两个方程,4个未知量,同时知道这四个未知量的范围,那我们就可以枚举两个未知量,解剩下两个未知量,满足就输出。
a+b+c+d= n/2;
b+c+2d=nb+nd;
解出c = n - 2 * (a + b) - nb - nd + b;
d = n / 2 - c - a - b;
暴力枚举a,b,然后解出c,d,判断满不满足,满足就输出
#include<bits/stdc++.h> using namespace std; typedef long long ll; vector<int> aa, bb, cc, dd; const int N = 5e3 + 10; int n,na,nb,nc,nd; int a[N], c[N]; int main() { cin >> n; for (int i = 0; i < n; i++) scanf("%1d", &a[i]); for (int i = 0; i < n; i++) scanf("%1d", &c[i]); for (int i = 0; i < n; i++) { if (a[i] == 0 && c[i] == 0) na++, aa.push_back(i+1); else if (a[i] == 0 && c[i] == 1) nb++, bb.push_back(i+1); else if (a[i] == 1 && c[i] == 0) nc++, cc.push_back(i+1); else nd++, dd.push_back(i+1); } for (int a = 0; a <= na; a++) { for (int b = 0; b <= nb; b++) { int c = n - 2 * (a + b) - nb - nd + b; if (c >= 0 && c <= nc) { int d = n / 2 - c - a - b; if (d >= 0 && d <= nd) { //cout << a << b << c << d << endl; for (int i = 0; i < a; i++) printf("%d ", aa[i]); for (int i = 0; i < b; i++) printf("%d ", bb[i]); for (int i = 0; i < c; i++) printf("%d ", cc[i]); for (int i = 0; i < d; i++) printf("%d ", dd[i]); printf("\n"); return 0; } } } } printf("-1\n"); return 0; }