2021牛客暑期多校训练营1-Knowledge Test about Match

题目链接

题意:数组a={0,1,2…n-1},现在给定一个数组b,你可以随意交换b中的元素,定义损失函数f(a,b)= ∑ 1 n \sum_1^n 1n a b s ( a i − b i ) \sqrt{abs(ai-bi)} abs(aibi) ,要求你交换后的b数组与a数组的损失函数和最小损失函数在T组的平均偏差小于0.04

这题不会验证做法的正确性,但还是来讲下蒟蒻补题思路:暴力的去不断地减小损失函数,循环拿出i,j两个位置的b,如果 ( a b s ( b i − i ) ) \sqrt{(abs(bi-i))} (abs(bii)) + ( a b s ( b j − j ) ) \sqrt{(abs(bj-j))} (abs(bjj)) > ( a b s ( b i − j ) ) \sqrt{(abs(bi-j))} (abs(bij)) + ( a b s ( b j − i ) ) \sqrt{(abs(bj-i))} (abs(bji)) 的话就交换ai,bj,只遍历一次时间为O(n*n),为了保证正确性,自然要尽可能的多的重复遍历(然而测了一下只要遍历次数大于2次就能过),由于 ∑ 1 n \sum_1^n 1nn<=40000,每一次n<=1000,所以n=1000至多40次,此时时间复杂度大约为1e7级别,可以选择10次左右

AcCode

#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdio>
#include<cmath>

#define inf 0x3f3f3f3f

using namespace std;

const int N = 1e4 + 100;

double sqt[N];
int arr[N];

inline void init() { for (int i = 1; i < N-10; i++) sqt[i] = sqrt((double)i); }

inline int abs(int x, int y) { return (x > y) ? (x - y) : (y - x); }

inline double S(int x, int y) { return sqt[abs(x - y)]; }

signed main() {
	init();
	int t;
	scanf("%d", &t);
	while (t--) {
		int n;
		scanf("%d", &n);
		for (int i = 1; i <= n; i++) scanf("%d", &arr[i]);
        int maxup = 10;
		for (int k = 1; k <=maxup ; k++) {
			for (int i = 1; i <= n; i++) {
				for (int j = i + 1; j <= n; j++) {
					if ((S(arr[i], (i-1)) + S(arr[j], (j-1))) > (S(arr[i], (j-1)) + S(arr[j], (i-1)))) {
						swap(arr[i], arr[j]);
					}
				}
			}
		}
		for (int i = 1; i <= n; i++) printf("%d ", arr[i]);
		printf("\n");

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值