2025牛客寒假算法基础集训营1 (E)
[!note] 比赛链接 https://ac.nowcoder.com/acm/contest/953231
A.茕茕孑立之影
题目标签
构造 数论
题目大意
找到一个数x,x和长度为n的数组中的数互不为倍数,找不到输出-1
,否则输出这个数.
解题思路
- 数组中出现1,则输出-1,任何数都是1的倍数
- 其他情况下输出范围内的最大数即可 (
1e9+7
)
#include <bits/stdc++.h> using namespace std; void solve(){ int n;cin >> n; int arr[n]; for(int i=0;i<n;i++){ cin >> arr[i]; } for(auto x : arr){ if(x == 1) { cout << -1 << endl; return; } } int ans = 1e9 + 7; cout << ans << endl ; } int main(){ int t;cin >>t; while(t--){ solve(); } return 0; }
B. 一气贯通之刃
题目标签
图论
题目大意
在树上寻求简单路径问题,路径不重复不遗漏所有节点,不存在这个路径输出-1
解题思路
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; vector<int> d(n+1); for (int i =0; i<n-1;i++) ~{ int u,v; cin>>u>>v; d[u]++; d[v]++; } bool b = true; vector<int> l; for (int i=1;i<=n;i++) { if (d[i] > 2) b = false; if (d[i] == 1) l.push_back(i); } if (b && l.size() == 2) cout << l[0] << ' ' << l[1] << endl; else cout << -1 << endl; return 0; }
虽然AB解出来了,但是写都写了就不舍得删掉了 留着把
E. 双生双宿之错
题目描述
小红定义一个数组是“双生数组”,当且仅当该数组大小为偶数,数组的元素种类恰好为2种,且这两种元素的出现次数相同。例如
现在小红拿到了一个长度为偶数的数组,她可以进行若干次操作,每次操作将选择一个元素,使其加1或者减1。小红希望你计算将该数组变成双生数组的最小操作次数。
输入描述:
每个测试文件均包含多组测试数据。第一行输入一个整数
- 第一行输入一个正偶数
代表数组元素数量。 - 第二行输入
个正整数 代表数组元素。
除此之外,保证单个测试文件的
输出描述:
对于每组测试数据,新起一行。输出一个整数,代表将该数组变成双生数组的最小操作次数。
测试用例
示例1
- 输入
3 4 1 1 3 1 4 6 6 6 6 6 1 1 4 4 1 4
- 输出
2 2 0
解题思路
现将数组排序,分成前后两端,分别找出中位数,然后计算出操作次数,若前后中位数相同,前段-1 或后段+1 取最优解。
AC代码
#include <bits/stdc++.h> using ll = long long; using namespace std; #define all(a) a.begin(), a.end() #define endl '\n' #define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) void solve(){ int n; cin >> n; vector<int> a(n); for(auto &x : a) cin >> x; sort(all(a)); int h = n / 2; int ml = a[h /2],mr = a[h + h/2]; ll ans = LLONG_MAX; for(auto xl : {ml,ml - 1}){ for(auto xr : {mr,mr + 1}){ if(xl == xr){ continue; } ll res = 0; for (int i = 0; i < h; i++){ res += abs(a[i] - xl); res += abs(a[h + i] - xr); } ans = min(ans,res); } } cout << ans << endl; } signed main(){ ios; int _ = 1; cin >> _; while (_--) solve(); return 0; }
M. 数值膨胀之美
题目描述
定义一个数组的极差为:数组的元素最大值减去最小值。
小红拿到了一个数组,她准备进行恰好一次操作:选择一个非空区间,将其中所有元素都乘以 2。
小红希望最小化数组的极差,你能帮帮她吗?
输入描述
第一行输入一个正整数
第二行输入
输出描述
输出一个整数,代表操作恰好一次后,数组的最小极差。
解题思路
优先将最小值翻倍,扩大区间时应从最小值往次小值从小到大扩展
赛时代码
#include <bits/stdc++.h> using namespace std; #define int long long #define endl '\n' int _=1; void solve(){ int n;cin >> n; vector<int > a(n); for(int i=0;i<n;i++){ cin >> a[i]; } sort(a.begin(),a.end()); int t_max,t_min; t_max = a[n-1]; t_min = a[0]; if(t_max == t_min) { cout << 0 << endl; return; } int n_max=a[n-2]; int n_min=a[1]; int diff1 = abs (max(t_max,t_min*2) - min(t_min*2,n_min)); int diff2 = abs (max(t_max*2,n_max) - min(t_min*2,n_min)); cout << abs(min(diff1,diff2)); } signed main(){ //cin >> _; while(_--){ solve(); } return 0; }
~~赛时使用差分进行计算,由于数据弱了,蒟蒻骗到AC,赛后增强hack数据,该方法已经失效、
AC代码
~~没有,蒟蒻就会这么多了 >v< 也有可能是前世的记忆还未恢复,后面的区域,以后再来探索把 )
End...
本文作者:Hmi
本文链接:https://www.cnblogs.com/hmi1234/p/18692135
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步