続行...?(思考)

  • 継続する…?
  • 質問の意味
    クラスには1、2、3 ... Nの番号が付けられたN人の学生がいて、i番目の学生はi個の宝石を持っています。これらのN人の学生をG1、G2、G3、G4の4つのグループに分け、次のルールを満たしましょう。
  1. 各学生は1つのグループにのみ割り当てることができます
  2. 女性の学生はG1またはG2グループにのみ割り当てることができ、男性の学生はG3またはG4グループにのみ割り当てることができます(これらのN人の学生の性別は文字列の形式で示され、「1」は男性の学生を意味し、「0」は女性の学生を意味します)
  3. G1 + G3の宝石の数は、G2 + G4の宝石の数と同じです。
  4. 空のグループを1つ許可する

N人の生徒がどのグループに割り当てられているかを尋ねます。複数の回答がある場合は、自由に1つ出力してください。

  • アイデア
  1. 最初に不可能な状況を考えてみましょう。G1の
    宝石の数はsum1sum_1です。s u m1
    G2の宝石の数は合計2ですsum_2s u m2
    G3の宝石の数は合計3ですsum_3s u m3
    G4の宝石の数は合計4ですsum_4s u m4
    合計1+合計3 ==合計2+合計4sum_1 + sum_3 == sum_2 + sum_4s u m1+s u m3==s u m2+s u m4
    合計1+合計2+合計3+合計4 = = N ∗(N + 1)/ 2 sum_1 + sum_2 + sum_3 + sum_4 == N *(N + 1)/ 2 s u m1+s u m2+s u m3+s u m4==NN+1 / 2
    2 ∗(合計1 +合計3)= = N ∗(N + 1)/ 2 2 *(sum_1 + sum_3)== N *(N + 1)/ 22s u m1+s u m3==NN+1 / 2
    したがって、N *(N + 1)/ 2が偶数でない場合は、直接-1を出力します。

  2. 可能であれば、それをどのように割り当てるのですか?
    まず、合計1+合計3 ==合計2+合計4を満足する方法を検討しますsum_1 + sum_3 == sum_2 + sum_4s u m1+s u m3==s u m2+s u m4
    宝石の数は連続する1〜Nなので、次のように割り当てることができます。たとえば、N = 7、宝石の数は1 2 3 4 5 6 7で、ペア(6,7)、(4,5)、( 2,3)、(1)

    7ポイントを1、3(1つは性別に依存)、6ポイントを2、4(1つは性別に依存)、
    4ポイントを1、3(1つは性別に依存)、5ポイントを2、4(1つは特定に依存)とします。性別)
    3ポイントを1、3(1つは性別に依存)、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