codeforces 题目 Permutation

目录

题目:

题目描述:

思路:

AC代码:


题目:

题目描述:

给你n,k,请你构造一个长度为 2n 的序列,使他满足下面的条件:

思路:

当你实际操作起来你会发现这个公式其实不难理解

我们可以规定序列中从头开始连续的(奇数位,偶数位)两两一组(因为长度为 2n 所以总共 n 组),那么这个公式求的就是,前半部分所有组内的差值的绝对值的和 减去 所有组内的差值的和的绝对值

不妨,我们先拿 1 到 2n 的顺序序列试试水,发现在这种情况下,总和等于 0

如果我们对其中一组中两个数进行交换位置呢?会发现总和上升了 2

如果我们把所有的组( n 组 )进行翻转呢?我们会发现.....总和又变回 0 了

如果我们把一半的组( n / 2 组 )进行翻转呢?我们发现总和上升到了 n ,这就对应了公式结果 2k 以及题目中 2k 的取值范围小于等于 n ,这就说明这就是上界。

那么我们可以得出思路,k就代表着我需要翻转的组数,其他组按照正常顺序输出就行。

(不想听我分析的可以直接看代码了)


为什么我们可以这么干?是因为,每当我们进行翻转的时候,前半部分公式的值永远等于 n

而后半部分会随着翻转的组数而改变:

每翻转一个组,会导致差值的变为原来的相反数( 如 -1 变成 1 )这样的变化会导致后半部分的值比原来小 2,从而导致总值多 2 

换句话讲,我每翻转一组,都会减少了自身的贡献的同时,还抵消了另一个没有翻转的组的贡献。这也就是为什么对一半的组( n / 2 )的组进行翻转会得到最大值。

思路有了,具体操作请看AC代码

AC代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

int main()
{
	std::ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	int n, k;
	cin >> n >> k;

	for (int i = 1; i <= n; i++)
	{
		if (k)
		{
			cout << 2 * i << ' ' << 2 * i - 1 << ' ';
			k--;
		}
		else
		{
			cout << 2 * i - 1 << ' ' << 2 * i << ' ';
		}
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值