浙江省赛 CONTINUE...? (思维)

  • CONTINUE…?
  • 题意
    班里有N名同学,编号为1、2、3……N,第i名同学有i个宝石。让我们将这N名学生分成G1,G2,G3,G4四个组,且满足以下规则
  1. 每一个同学仅且只能分到一个组
  2. 女同学只能分到G1或者G2组,男同学只能分到G3或者G4组 (这N个同学的性别会以字符串的形式给出,‘1’表示男同学,‘0’表示女同学)
  3. G1+G3的宝石数量等于G2+G4的宝石数量
  4. 允许有一个组为空

问这N个同学各自分到了那一组,如果答案有多种,随意输出一种即可。

  • 思路
  1. 我们先考虑不可能的情况, 假设:
    G1的宝石数量是 s u m 1 sum_1 sum1
    G2的宝石数量是 s u m 2 sum_2 sum2
    G3的宝石数量是 s u m 3 sum_3 sum3
    G4的宝石数量是 s u m 4 sum_4 sum4
    s u m 1 + s u m 3 = = s u m 2 + s u m 4 sum_1+sum_3==sum_2+sum_4 sum1+sum3==sum2+sum4
    s u m 1 + s u m 2 + s u m 3 + s u m 4 = = N ∗ ( N + 1 ) / 2 sum_1+sum_2+sum_3+sum_4==N*(N+1)/2 sum1+sum2+sum3+sum4==N(N+1)/2
    2 ∗ ( s u m 1 + s u m 3 ) = = N ∗ ( N + 1 ) / 2 2*(sum_1+sum_3)==N*(N+1)/2 2(sum1+sum3)==N(N+1)/2
    所以如果N*(N+1)/2不是偶数的直接输出-1了

  2. 如果可能的话,该如何分配呢?
    先考虑如何满足 s u m 1 + s u m 3 = = s u m 2 + s u m 4 sum_1+sum_3==sum_2+sum_4 sum1+sum3==sum2+sum4
    因为宝石的数量是连续的1~N,我们可以这样分配,比如N=7,宝石 数量是 1 2 3 4 5 6 7,从后面两两分组(6,7),(4,5),(2,3),(1)

    让7分给1、3(具体哪个看性别),6分给2、4(具体哪个看性别)
    让4分给1、3(具体哪个看性别),5分给2、4(具体哪个看性别)
    让3分给1、3(具体哪个看性别),2分给2、4(具体哪个看性别)

    这样能保证1、3和2、4的差值最大是1(只有N%4不为0的情况差值为1,这时前面的1还没用,正好补上这个差值)

  • 代码
#pragma GCC optimize(2)
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long ul;
typedef unsigned long long ull;
#define pi acos(-1.0)
#define e exp(1.0)
#define pb push_back
#define mk make_pair
#define fir first
#define sec second
#define scf scanf
#define prf printf
typedef pair<ll,ll> pa;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int MAX_N=1e5+7;
int N,T;
char s[MAX_N];
int res[MAX_N];//记录答案 
int main()
{
    
    
//  freopen(".../.txt","w",stdout);
//  freopen(".../.txt","r",stdin);
	ios::sync_with_stdio(false);
	cin>>T;
	int i,j;
	while(T--){
    
    
		cin>>N;
		cin>>s+1;
		int sum=N*(N+1)/2;
		if(sum&1){
    
    
			cout<<-1<<endl;
			continue;
		}
		bool flag=1;
		for(i=N;i>=1;i-=2){
    
    
			if(flag){
    
    //大的放到1或者3里面 
				res[i]=(s[i]=='1'?3:1);
				res[i-1]=(s[i-1]=='1'?4:2);
			}
			else{
    
    //大的放到2或者4里面 
				res[i-1]=(s[i-1]=='1'?3:1);
				res[i]=(s[i]=='1'?4:2);
			}
			flag=!flag;//1、3和2、4交替着放大的,这样才能保证1、3的和与2、4的和最大相差1 
		}
		if(N%4){
    
    //没有分均衡,将最后一个1分配给2、4(因为我们先给1、3分配的,如果不够的话也是2、4不够) 
			if(s[1]=='1')
			res[1]=4;
			else
			res[1]=2;
		}
		for(i=1;i<=N;i++){
    
    
			cout<<res[i];
		}
		cout<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43311695/article/details/108912582