D. Vupsen, Pupsen and 0(构造)

题目:D. Vupsen, Pupsen and 0

题目链接:https://codeforces.ml/contest/1582/problem/D

题意:给出一个长度为n的数组a,保证数组元素都不为0,求构造任意一个长度为n,且元素都不为0的数组b,使得

  1.  a1 * b1 + a2 * b2 + a3 * b3 + …… + an * bn = 0,
  2.  |b1|+|b2|+…+|bn| <= 1e9。

输入描述:

第一行输入测试用例个数t。

t个测试用例。每个测试用例第一行输入n(2 <= n <= 1e5),第二行给出数组a的n个元素ai(-1e4 <= ai <= 1e4, ai ≠ 0)。

输出描述:

对于每个测试用例,输出数组b。

样例输入:

1

2

5 5

样例输出:

1 -1

样例解释:5 * 1 + 5 * (-1) = 0且|b1|+|b2| = 1 + 1 = 2 <= 1e9。

题目分析:构造。显然,对于任意两个非零数ai, aj,都可以构造出bi = aj, bj = -ai  使得ai * bi + aj * bj = 0。

解题步骤:当n为偶数时,可以找出n / 2对ai, aj,构造bi = aj, bj = -ai,此时|b1|+|b2|+…+|bn| = |a1|+|a2|+…+|an| <= 1e4 * 1e5 = 1e9。当n为奇数时,可以挑出3个元素,ai, aj, ak,因为这三个元素都不等于0,根据抽屉原理,一定有两个元素同正或者同负,即一定存在两个元素相加不等于0。假设有ai + aj ≠ 0,那么可以构造bi = ak, bj = ak, bk = -(ai + aj),使得ai * bi + aj * bj + ak * bk = 0。n为奇数,n – 3一定为偶数或0,那么剩下的元素则可以按n为偶数时的方法构造出对应的b数组中的元素。此时|b1|+|b2|+…+|bn| = |a1|+|a2|+…+|an| <= 1e4 * 1e5 = 1e9。

错误:赛时有想到对于ai, aj,可以构造bi = aj, bj = -ai。但却想把第一个元素挑出来作为ai,然后其他元素的和作为aj来构造b数组,结果就是因为b数组元素的和可能大于1e9而WA。

 

AC代码:

#include<iostream>

 

using namespace std;

const int N = 1e5 + 10;

int a[N], b[N];

 

void solve(){

        int n;

        scanf("%d", &n);

        for(int i = 1;i <= n;i++) scanf("%d", &a[i]);

       

        if(n & 1){

                 int x = n - 3;

                 for(int i = 1;i <= x;i++){

                         if(i & 1) b[i] = a[i + 1];

                         else b[i] = -a[i - 1];

                 }

                

                 if(a[n - 2] + a[n - 1] != 0){

                         b[n - 2] = b[n - 1] = a[n];

                         b[n] = -(a[n - 2] + a[n - 1]);

                 }

                 else if(a[n - 2] + a[n] != 0){

                         b[n - 2] = b[n] = a[n - 1];

                         b[n - 1] = -(a[n] + a[n - 2]);

                 }

                 else if(a[n - 1] + a[n] != 0){

                         b[n - 1] = b[n] = a[n - 2];

                         b[n - 2] = -(a[n - 1] + a[n]);

                 }

        }

        else{

                 for(int i = 1;i <= n;i++){

                         if(i & 1) b[i] = a[i + 1];

                         else b[i] = -a[i - 1];

                 }

        }

       

        for(int i = 1;i <= n;i++) printf("%d ", b[i]);

        printf("\n");

}

 

int main(void){

        int t;

        scanf("%d", &t);

        while(t--) solve();

       

        return 0;

}

时间复杂度:O(n)。

空间复杂度:O(n)。

posted @   思丶君  阅读(163)  评论(3编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示