「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\\)

分类讨论

  1. \\(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」魔仙的主要内容,如果未能解决你的问题,请参考以下文章

魔仙智能机器人

团队作业4分数发布

微信小程序代码片段

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?