COMPFEST 14 - Preliminary Online Mirror (Unrated, ICPC Rules, Teams Preferred) H. Hot Black Hot Whit

 

 翻译:

有一天,你会成为查内克医生的助理。查内克医生给你的第一个任务就是保管好他的魔法宝石。

查内克博士有𝑁的魔法石,𝑁是偶数。那些魔法石头的编号从1到𝑁。魔法石𝑖有𝐴𝑖的力量。一块神奇的石头可以被涂上两种颜色,即黑色或白色。你的任务是将魔法石头涂成黑色或白色,并将魔法石头储存在一个魔法系数𝑍(0≤𝑍≤2)的魔法盒子中。魔法石的绘画必须以这样一种方式进行,即有𝑁2黑色魔法石和𝑁2白色魔法石。

为两个整数𝑥和𝑦定义concat(𝑥,𝑦),这是将𝑥在𝑦左侧的数字在其十进制表示中连接的结果,而不改变顺序。例如,concat(10,24)的结果是1024。

魔盒与魔法系数𝑍,魔法石𝑖与魔法石𝑗反应如果石头的颜色是不同的,concat(𝐴𝑖,𝐴𝑗)×concat(𝐴𝑗,𝐴𝑖)+𝐴𝑖×𝐴𝑗≡𝑍mod3。有反应的魔法石头会很热很危险。因此,你必须给魔法石头上色,并确定魔法盒子的魔法系数𝑍,以确保没有魔法石头发生反应,或者报告是否不可能发生反应。

输入
第一行包含一个偶数整数𝑁(2≤𝑁≤105)——Chanek博士拥有的魔法宝石的数量。

第二行包含𝑁integer𝐴1,𝐴2,…,𝐴𝑁(1≤𝐴𝑖≤109)——所有魔法宝石的强度。

输出
如果不可能满足问题的条件,则输出−1。

否则,输出两行。第一行包含一个整数𝑍,表示魔术框的魔术系数。第二行包含长度为𝑁的字符串𝑆。如果魔法石𝑖是黑色的,𝑆𝑖为0;如果魔法石𝑖是白色的,则为1。如果有不止一种着色和选择神奇系数𝑍的可能性,输出其中任何一种。

例子
inputCopy
4
4 10 9 14
outputCopy
0
1001
请注意
通过给出以上颜色,可以看出:

𝑖= 1,𝑗= 2⟶concat(4、10)×concat(10, 4) + 10×4 = 410×104 + 40 = 42680≡2 mod3
𝑖= 1,𝑗= 3⟶concat(4、9)×concat(9, 4) + 4×9 = 49×94 + 36 = 4642≡1 mod3
𝑖= 4,𝑗= 2⟶concat(14日10)×concat(10, 14) + 10×14 = 1410×1014 + 140 = 1429880≡2 mod3
𝑖= 4,𝑗= 3⟶concat(14日9)×concat(9、14)+ 14×9 = 149×914 + 126 = 136312≡1 mod3
正因为如此,通过选择𝑍=0,可以保证没有魔法石发生反应。

思路:数论题,可以化简,然后根据起情况分类讨论分析。

代码实现:

#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<tuple>
#include<numeric>
using namespace::std;
typedef long long  ll;
inline __int128 read(){
    __int128 x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if(ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
inline void print(__int128 x){
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x > 9)
        print(x / 10);
    putchar(x % 10 + '0');
}
int n;
ll a[100005];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(); cout.tie();
    cin>>n;
    ll an=0,bn=0,cn=0;
    for (int i =1; i<=n; i++) {
        cin>>a[i];
        a[i]=(a[i]*a[i])%3;
        if (a[i]==0) {
            
            an++;
        }
        else if (a[i]==1)
        {
            bn++;
        }
        else{
            cn++;
        }
    }
//    for (int i =1; i<=n; i++) {
//        printf("%lld ",a[i]);
//    }
//    printf("\n");
//    printf("%lld %lld %lld\n",an,bn,cn);
    if (an==n/2) {
        printf("0\n");
        for (int i =1; i<=n; i++) {
            if (a[i]==0) {
                printf("1");
            }
            else{
                printf("0");
            }
        }
        printf("\n");return 0;
    }
    if (bn==n/2) {
        printf("2\n");
        for (int i =1; i<=n; i++) {
            if (a[i]==1) {
                printf("1");
            }
            else{
                printf("0");
            }
        }
        printf("\n");return 0;
    }
    if (cn==n/2) {
        printf("1\n");
        for (int i =1; i<=n; i++) {
            if (a[i]==2) {
                printf("1");
            }
            else{
                printf("0");
            }
        }
        printf("\n");return 0;
    }
    if (an==0) {
        if (bn>=cn) {
            printf("1\n");
            bn=bn-cn;
            bn/=2;
            for (int i=1 ; i<=n; i++) {
                if (a[i]==1) {
                    if (bn) {
                        printf("1");
                        bn--;
                    }
                    else{
                        printf("0");
                    }
                }
                else{
                    printf("1");
                }
            }
        }
        else{
            printf("2\n");
             cn=cn-bn;
            cn/=2;
            for (int i=1 ; i<=n; i++) {
                if (a[i]==2) {
                    if (cn) {
                        printf("1");
                        cn--;
                    }
                    else{
                        printf("0");
                    }
                }
                else{
                    printf("1");
                }
            }
            
        }
        printf("\n");
        return 0;
    }
    if (bn==0) {
        if (an>=cn) {
            printf("1\n");
             an=an-cn;
            an/=2;
            for (int i=1 ; i<=n; i++) {
                if (a[i]==0) {
                    if (an) {
                        printf("1");
                        an--;
                    }
                    else{
                        printf("0");
                    }
                }
                else{
                    printf("1");
                }
            }
        }
        else{
            printf("0\n");
            cn=cn-an;
            cn/=2;
            for (int i=1 ; i<=n; i++) {
                if (a[i]==2) {
                    if (cn) {
                        printf("1");
                        cn--;
                    }
                    else{
                        printf("0");
                    }
                }
                else{
                    printf("1");
                }
            }
            
        }
        printf("\n");
        return 0;
    }
        if (cn==0) {
            if (bn>=an) {
                printf("0\n");
                 bn=bn-an;
                bn/=2;
                for (int i=1 ; i<=n; i++) {
                    if (a[i]==1) {
                        if (bn) {
                            printf("1");
                            bn--;
                        }
                        else{
                            printf("0");
                        }
                    }
                    else{
                        printf("1");
                    }
                }
            }
            else{
                printf("2\n");
                an=an-bn;
                an/=2;
                for (int i=1 ; i<=n; i++) {
                    if (a[i]==0) {
                        if (an) {
                            printf("1");
                            an--;
                        }
                        else{
                            printf("0");
                        }
                    }
                    else{
                        printf("1");
                    }
                }
                
            }
            printf("\n");
            return 0;
        }
        
    
    printf("-1\n");
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值