牛客挑战赛67-A-构造(C)

链接:https://ac.nowcoder.com/acm/contest/51727/A
来源:牛客网 

aaca31a79c6542dbb74891ffa8300444.png

首先看题。题目意思是说,让我们构造一个p[2*n]的数组,其中呢,有一个元素的是确定的,就是那个p[a]=b,还有一个要求,就是说,前面相加的和不能够等于后面相加的和

现在来看看样例

输入为

3
2 3 4
4 6 1
5 1 3

输出为

3 1 4 2
2 3 7 5 6 1 4 8
3 1 6 10 2 4 7 8 9 5

按照题目的意思,结合样例一分析的话就是 (:为了方便构造,数组都是从1开始的)

有数组p[4],其中p[3]=4,并且要满足 前面相加的和不能够等于后面相加的和 。即:

p[1]!=p[4] (3!=2)

p[1]+p[2]!=p[3]+p[4] (4!=6)

思路就是呢,因为p[a]=b是固定的,比较好满足,所以主要满足“ 前面相加的和不能够等于后面相加的和 ”这个条件就好了。

知道的是,如果是一串从小到大排好的数组,必满足那个要求( 前面相加的和不能够等于后面相加的和),因为大的数跟大的数相加肯定不会等于小的数。所以,应该是把大的数放在一边,把小的数放在另外一边就好了。

我们以n为分界点,

当a<=n时,可以确定,p[a]是在左边的,b<=n,则说明左边应该是小的那一部分数(左小右大);

依此类推,a>n&&b>n 也是左小右大的情况,而a<=n&&b>n和a>n&&b<=n为左大右小

所以说,只需要分成两种情况就好了,一个是左小右大,一个是左大右小。

左小右大,此情况,我的思路是

先让数组初始化,从小到大,即p[1]=1, p[2]=2...p[2*n]=2*n。

然后在考虑特殊的p[a]=b,若p[a]!=b,就把p[a]与等于b的p[i]交换一下就好了。

左大右小,就是从大到小初始化数组p[N],基本思路跟上面一样。

代码如下

#include<stdio.h>
#define N 400100
int main()
{
    long t,p[N];
    scanf("%ld",&t);
    while(t--)
    
    {
        int n,a,b,i,j=1,t,s;
        scanf("%d%d%d",&n,&a,&b);
    
        if((a<=n&&b<=n)||(a>n&&b>n))//左小右大
        {
            for(i=1;i<=2*n;i++)
            {
                p[i]=j++; 
                if(p[i]==b)
                    s=i;
            }
            t=p[a];
            p[a]=p[s];
            p[s]=t;
        }
        else //if((a<=n&&b>n)||(a>n&&b<=n))//左大右小
        {
            for(i=2*n;i>=1;i--)
            {
                p[i]=j++;
                if(p[i]==b)
                    s=i;
            }
            t=p[a];
            p[a]=p[s];
            p[s]=t;
        }
        for(i=1;i<=2*n;i++)
            printf("%d ",p[i]);
        printf("\n");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值