「MCOI-05」魔仙
Posted 归游
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「MCOI-05」魔仙相关的知识,希望对你有一定的参考价值。
「MCOI-05」魔仙
简化题意
构造一个数组\\(a_i\\)
\\(\\sum_1^{n}a_i=0\\)
\\(\\prod_1^{n}a_i=n\\)
根据第一个条件
其实很容易想到,构造一对相反数
再根据第二个条件
使这对相反数乘积为n
但光凭两个数根本不可能满足上述两种情况
一对相反数,只会有一个负数,而且乘积也为负数
所以很容易想到,再构造一对相反数,这对相反数存在的意义仅仅只是为把\\(-n\\)变为\\(n\\),所以为了不影响乘积 第二对相反数取\\(1和-1\\)
但会发现这仅仅只满足平方数
所以我们一般化一下
取\\(n\\)的任意两个因数\\(a,b\\) 使得\\(a*b=n\\)
此时第二对相反数\\(c,d\\)发挥更多的作用
为满足题意 所以 \\(a+b+c+d=0\\)
分类讨论
- \\(a\\)为负 \\(b\\)为正(令 \\(|a|<|b|\\))
那么此时需要 |b|-|a|个-1 这样目前的序列和则能为\\(0\\)
接下来就是 需要使乘积为n,现在整个序列乘积为\\(n\\)或\\(-n\\)
是\\(n\\)个话就直接添加\\(1\\)就可
是\\(-n\\)就要适量的\\(-1\\)使整个序列积为\\(n\\)
2.\\(a,b\\)同正(同负不过就是整个序列都乘\\(-1\\)而已)
先要\\(a+b\\)个\\(-1\\),然后适量添加\\(+1\\)或\\(-1\\)使序列和为\\(0\\),乘积为\\(n\\)
(这里讲下,免得后面的解释不太理解,两个同正的情况可以理解为两对相反数中抽出了两个正数)
思路到这就完了
可能有同学有疑惑?
1.无解的情况了??
\\(n mod 4!=0\\) 即为无解的情况
(非严格证明)
如果n为2的倍数则有可能出现 乘积为负数的情况
如果n为3的倍数则一定会出现 乘积为负数的情况
如果n为4的倍数则满足2不出现负数的情况且满足题意
(u1s1,其实可以不同特判,反正循环完了没输出应该就无解,没试过(逃)
- code
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int t;
int n;
const int maxn=1e6+10;
int prime[maxn];
bool isprime[maxn];
int cnt=0;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>t;
while(t--){
cin>>n;
if(n%4) cout<<"ZFYAKIOI"<<endl;
else {
int a,b;
for(int i=2;i<=n;++i){
if(n%i==0) {
a=i,b=n/i;
if(a==b){//平方数
cout<<b<<" "<<(-1)*a<<" ";
for(int i=1;i<=(n-2)/2;++i) cout<<"-1 1 ";
cout<<endl;
break;
}
else if(n-2>=a+b && ((n-2+a+b)/2)%2==0) {//同正
cout<<a<<" "<<b<<" ";
for(int i=1;i<=a+b;++i) cout<<"-1 ";
for(int i=1;i<=(n-2-a-b)/2;++i) cout<<"1 -1 ";
cout<<endl;
break;
}
else if((n-2-(b-a)/2)%2==0 && (n-2-b+a)%2==0) {//一正一负
cout<<b<<" "<<(-1)*a<<" ";
for(int i=1;i<=b-a;++i) cout<<"-1 ";
for(int i=1;i<=(n-2-(b-a))/2;++i) cout<<"-1 1 ";
cout<<endl;
break;
}
/* else if((n-2-a-b)%2==0 && (n-2-a-b)%4==0){//同负
cout<<(-1)*a<<" "<<(-1)*b<<" ";
for(int i=1;i<=(a+b);++i) cout<<"1 ";
for(int i=1;i<=(n-2-a-b)/2;++i) cout<<"-1 1 ";
cout<<endl;
break;
} */
}
}
}
} return 0;
}
以上是关于「MCOI-05」魔仙的主要内容,如果未能解决你的问题,请参考以下文章