专栏文章

题解:P14029 【MX-X20-T3】「FAOI-R7」重排序列(update)

P14029题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@minwtjoy
此快照首次捕获于
2025/12/02 09:39
3 个月前
此快照最后确认于
2025/12/02 09:39
3 个月前
查看原文

解题思路

贪心。
先把两个数组的数字、除 mm 的余数、当前的位置 ii 都存到一个结构体里面,对 aa 按余数从大到小、bb 按余数从小到大排序,以便后续操作。
然后再贪心。把 bb 中的最小的余数在 aa 中一个一个试,若它们两个加起来小于 mm,则成功配对。再把 bb 中的第二小的余数在 aa 中接着试……这样,就可以尽可能地减少模 mm 对答案造成的影响。
对于不满足条件的数字,任意两两配对即可。可以证明这时两个数加起来大于等于 mm、小于 2×m2\times m,所以不管如何模 mm 后都要减少 mm。然后,记录减少 mm 的数量 ssss,计算答案时直接减 ss×mss\times m 即可。
注意输出方案时要按原来的顺序(即用数组记录一下)。

Code

CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
struct node
{
	int x,y,z;
}a[200010],b[200010];
int ans[200010];
bool cmp (node xx,node yy){return xx.y>yy.y;}
bool cmpp(node xx,node yy){return xx.y<yy.y;}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin>>t;
	while(t--)
	{
		int n,m,noww,now=1,s=0,ss=0;
		cin>>n>>m;noww=n;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i].x;
			s+=(a[i].y=a[i].x%m);
			a[i].z=i;
		}
		for(int i=1;i<=n;i++)
		{
			cin>>b[i].x;
			s+=(b[i].y=b[i].x%m);
			b[i].z=i;
		}
		sort(a+1,a+n+1,cmp);
		sort(b+1,b+n+1,cmpp);
		for(int i=1;i<=n;i++)
			if(a[i].y+b[now].y>=m)
			{
				ans[a[i].z]=b[noww--].x;
				ss++;
			}
			else ans[a[i].z]=b[now++].x;
		cout<<s-ss*m<<'\n';
		for(int i=1;i<=n;i++)
			cout<<ans[i]<<' ';
		cout<<'\n';
	}
	return 0;
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...