CF798C Mike and gcd problem
2024-08-29 16:20:07
思路:
首先如果数列的最大公约数大于1,直接输出即可。
否则,设对原数列中的ai和ai+1进行一次操作,分别变为ai - ai+1和ai + ai+1。设新数列的最大公约数为d,则由于d|(ai - ai+1)并且d|(ai + ai+1)得到d|(2ai)且d|(2ai+1)。则d|gcd(a1, a2, ..., 2ai, 2ai+1, ai+2, ..., an)|2gcd(a1, a2, ..., an) = 2。说明进行一次这样的操作最多可以把最大公约数变为原来的2倍。所以我们的目标就是把数列的最大公约数变成2(即把所有的数都变成偶数)。
奇数 + 奇数 = 偶数,奇数 + 偶数 = 奇数,偶数 + 偶数 = 偶数。把奇偶性不同的相邻的两个数都变成偶数需要2次操作,而把相邻的两个奇数都变成偶数需要1次操作,所以首先优先把相邻的奇数处理掉,再处理奇数和偶数相邻的情况。
实现:
#include <iostream>
using namespace std; int gcd(int a, int b)
{
return !b ? a : gcd(b, a % b);
} int n, a[]; int main()
{
cin >> n;
int g = ;
for (int i = ; i < n; i++)
{
cin >> a[i];
if (!i) g = a[i];
else g = gcd(g, a[i]);
}
if (g > )
{
puts("YES\n0\n"); return ;
}
int cnt = ;
for (int i = ; i < n; i++)
{
if (!(a[i] & )) continue;
else if (i + < n)
{
if (a[i + ] & ) cnt++;
else cnt += ;
i++;
}
else cnt += ;
}
cout << "YES" << endl << cnt << endl;
return ;
}
标程:
# include <bits/stdc++.h>
using namespace std;
# define fi cin
# define fo cout
int main(void)
{
int n;
fi>>n;
int g = ,v,cnt = ,ans = ;
while (n --)
{
int v;
fi>>v;
g = __gcd(g,v);
if (v & ) ++cnt;
else ans += (cnt / ) + * (cnt & ),cnt = ;
}
ans += (cnt / ) + * (cnt & );
fo << "YES\n";
if (g == )
fo << ans << '\n';
else
fo << "0\n";
cerr << "Time elapsed :" << clock() * 1000.0 / CLOCKS_PER_SEC << " ms" << '\n';
return ;
}
最新文章
- Day1(2016/1/21)——Beginning
- linux下的daemon进程
- jQuery+PHP实现浏览更多内容
- PHP CURL实现远程下载文件到本地
- PHP LINUX Notice: undefined $_GET完美解决方法
- 编译inotify报错
- viewWillLayoutSubView
- POJ 3978 Primes(求范围素数个数)
- 解决phpmyadmin-1800秒超时链接失效问题
- c++,模板函数的定义和使用【初探】
- Swift 2.2 协议和代理
- 【转】Android-Input 触控笔
- 使用 boot-repair 对 Windows + Ubuntu 双系统引导修复
- java基础概念整理(三)
- BZOJ.5285.[AHOI/HNOI2018]寻宝游戏(思路 按位计算 基数排序..)
- day1 diff命令递归比较目录下的文件
- jupyter notebook 在mac OS上的安装
- 使用std::map和std::list存放数据,消耗内存比实际数据大得多
- [工具]Tomcat CVE-2017-12615 远程代码执行
- 微信小程序里使用阿里巴巴矢量图标