CF1593D2 Half of Same

题目大意:

给定一个包含 \(n\)\(n\) 是偶数)个整数的数列 \(a_1,a_2,\ldots,a_n\)
考虑一个可能的正整数 \(k\),在每次操作中,你可以选定一个 \(i\),并将 \(a_i\) 减少 \(k\)
你可以执行任意多次(也可能是零次)操作,使这个数列中至少一半的数相等。
请找出最大的符合条件的 \(k\),如果 \(k\) 可以是任意的大小,输出 \(-1\)

观察题目,不难发现,满足输出 \(-1\) 的充要条件就是原数列里已经至少有一半的数相等了,因此输入后我们判断一下这种情况是否存在即可。
题目中的操作,实际上就等价于让我们寻找一个最大的 \(k\),使得数列中至少有一半的数关于它同余即可。我们在数列中选出 \(a\)\(b\),使得如下式子成立:

\[a\equiv b(\mod k) \]

以此推出,得:

\[k\mid (a-b) \]

这就说明,我们只需要枚举数列中任意两个数,将他们相减后得到的数设为 \(d\),枚举 \(d\) 的因数,寻找一个最大的因数使得数列中有至少一半的数关于它同余即可。

AC代码:

#include<bits/stdc++.h> using namespace std; const int MAXN = 10000000; int n,a[MAXN]; int t; map<int,int> m; int gcd(int a,int b){ if(!b){ return a; } return gcd(b,a % b); } int main(){ cin >> t; while(t--){ m.clear(); cin >> n; n /= 2; for(int i = 1; i <= 2 * n; i++){ cin >> a[i]; m[a[i]]++; } bool flagb = 0; for(int i = 1; i <= 2 * n; i++){ if(m[a[i]] >= n){ cout << "-1\n"; flagb = 1; break; } } if(flagb)continue; bool flag; int ans = 0; for(int l = 1; l <= 2 * n; l++){ //cout << 1 << "\n"; for(int r = l + 1; r <= 2 * n; r++){ for(int j = (int)(sqrt(abs(a[l] - a[r]))) + 1; j >= 1; j--){ if(abs(a[l] - a[r]) % j == 0 && abs(a[l] - a[r]) != 0){ flag = 1; int cnt = 0; for(int i = 1; i <= 2 * n; i++){ if((a[i] + MAXN) % j == (a[l] + MAXN) % j)cnt++; if(cnt == n){ ans = max(ans,j); break; } } cnt = 0; int h = abs(a[l] - a[r]) / j; for(int i = 1; i <= 2 * n; i++){ if((a[i] + MAXN) % h == (a[l] + MAXN) % h)cnt++; if(cnt == n){ ans = max(ans,h); break; } } } } } } cout << ans << "\n"; } return 0; }

__EOF__

本文作者Never Gonna Give You Up!
本文链接https://www.cnblogs.com/CZ-9/p/16500896.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   腾云今天首飞了吗  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示