题意
给定一个长度为n(n>=2)且不包含0的数组a,要求求一个数组b使得∑ai⋅bi=0(其中bi不等于0)也就是每个ai和bi的乘积的和等于0。要求∑abs(bi)<=1de9
思路
这种构造题思路一般不唯一,我只讲下我的构造方式,并不代表只有我这种是正解=3=。首先假设n为2,也就是a中的元素有a1和a2,对于两个数字我们有一种显而易见的构造方式,a1*(-a2)+a2*a1=0,也就是b1=-a2,b2=a1.那么我们的思路就清晰了,对于n长度>2的情况每次找两个没被用过数字构造成0,如果n的长度为偶数运行到结束就行了,如果n的长度为奇数,最后肯定剩下一个数字,剩下这个数字再随便找一个数字构造成0就行了,需要注意bi不能为0.
代码
#include<bits/stdc++.h>
using namespace std;
int T;
int n;
int a[100005];
int ans[100005];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);//a数组长度
for(int i=1;i<=n;i++)
ans[i]=0;//ans[i]即b[i]
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int l=1,r=n;
while(l<r)//每次取a[l]和a[r]两个数字构造0,也可以从前往后扫每次扫两个,思路正确就行
{
ans[l]=-a[r];
ans[r]=a[l];
l++,r--;
}
if(n&1)//n为奇数说明a[r]还没有被构造过
{
//选取a[1]和a[r]构造0
//构造的方法有两种:1.b[1]=b[1]-a[r],b[r]=a[1] 2.b[1]=b[1]+a[r],b[r]=-a[1]
//因为这样子操作后有可能使得b[1]为0,又因为a[r]!=-,所以两种构造方法中至少有一个不为0,判断一下就好了
if(ans[1]-a[r]!=0)
{
ans[1]-=a[r];
ans[r]+=a[1];
}else
{
ans[1]+=a[r];
ans[r]-=a[1];
}
}
for(int i=1;i<=n;i++)//输出答案
printf("%d ",ans[i]);
printf("\n");
}
return 0;
}