翻译:
有一天,你会成为查内克医生的助理。查内克医生给你的第一个任务就是保管好他的魔法宝石。
查内克博士有𝑁的魔法石,𝑁是偶数。那些魔法石头的编号从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;
}