题目链接:传送门
题意:
四个组,G1、G2、G3、G4, G1和G2 只能分女生,G3和G4只能分男生。
问能否合理分配,是G1,G3两个组中的人手里的宝石 和 G2,G4两个组中人手里的宝石个数相同。
输入数据分析:
n = 7, 这组数据表明一共 7 个人。
1101001 。 这个字符串下标从 1 开始, 如 a[2] = 1,1 表明这个人是男生,如果 a[2] = 0 则表明这个人是女生, 他是第二个人,他手里有两块宝石,第 几个人就有几块宝石,下标就表示他(她)是第几个人 。
如果有多种分组方法,输出任意一种就行。
思路:
因为G1,G3 男女都可分入, G2,G4 也一样。
所以就不用去分男女了,可以把这个问题简化成分宝石。
简化问题如下: 有 1, 2,3, .... n。 有这样的 n 堆宝石,把他们平均分成两份,每堆宝石不可以拆分。
宝石总数 sum = n*(n+1)/2 , sum一定为偶数,如果是奇数无法均分。
由 sum 一定为偶数可得 n%4 == 0 || (n+1)%4 == 0 (请自行思考)
两种情况分别去分析:
(1) n%4 == 0 , 分宝石的方法可以固定,
举一个例子 1,2,3,4,5,6,7,8 。 一堆(G1,G3):1 ,8 , 3, 6 另外一堆(G2,G4) 2 , 7,4,5
(2) (n+1) % 4 == 0 <==> (n-3) % 4 == 0
将前三堆宝石,1,2 分给 G1,G2 , 3分给 3 。剩余的按 前一种方法去分就好了
分组已经完成,方法输出只需要考虑他是男是女就好了。
参考代码: 代码是练习赛的时候写的,有点乱,但是感觉这道题思路最重要,就不去重写代码了。
#include <iostream> #include <algorithm> using namespace std; const int N = 100010; char a[N]; char b[N]; int main() { int T, n; cin >> T; while(T--) { cin >> n; cin >> a; long long ans = n*(n+1)/2; if(n <= 2 || ans%2 == 1) { cout << "-1" << endl; } else { if(n % 2 == 0) { for(int i=0; i<=n/2-1; i++) { int j = n-i-1; if((i+1)%2 == 1) { if(a[i] == '1') b[i] = '3'; else b[i] = '1'; if(a[j] == '1') b[j] = '3'; else b[j] = '1'; } else { if(a[i] == '1') b[i] = '4'; else b[i] = '2'; if(a[j] == '1') b[j] = '4'; else b[j] = '2'; } } } else { if(a[0] == '1') b[0] = '3'; else b[0] = '1'; if(a[1] == '1') b[1] = '3'; else b[1] = '1'; if(a[2] == '1') b[2] = '4'; else b[2] = '2'; for(int i=3; i<3+(n-3)/2; i++) { int j = n-(i-2); if((i+1)%2 == 1) { if(a[i] == '1') b[i] = '3'; else b[i] = '1'; if(a[j] == '1') b[j] = '3'; else b[j] = '1'; } else { if(a[i] == '1') b[i] = '4'; else b[i] = '2'; if(a[j] == '1') b[j] = '4'; else b[j] = '2'; } } } b[n] = '\0'; cout << b << endl; } } return 0; }