codeforces 798C.Mike and gcd problem 解题报告
题目意思:给出一个n个数的序列:a1,a2,...,an (n的范围[2,100000],ax的范围[1,1e9] )
现在需要对序列a进行若干变换,来构造一个beautiful的序列: b1,b2, ..., bn,使得最大公约数 gcd(b1,b2,...,bn) > 1。
变换: 任意ai,ai+1 进行一次操作时,可以用 ai-ai+1, ai+ai+1 来替换。
问序列 a 构造成 序列 b ,使得gcd(b序列) > 1 的最小操作次数
题目解析:
首先,这个题目是肯定有解的,也就是恒输出yes
试想一下,相邻两个数之间无非就是四种情况:
(1)对于同偶情况,不需要做转换,公约数直接为2;
(2)对于同奇情况,只需要变换一次,两奇数进行加减操作,最终结果是偶数,公约数此时为2
(3)一奇一偶,变换两次: ai, ai+1 ——》 ai-ai+1, ai+ai+1 ——》2(ai+1,ai) ——》 公约数为2
此时问题就转化成: 构造一个序列所有数的公约数为2的最少操作次数。
当然,在处理序列之前,要先判断整个序列是否已经有公约数了(注意,并不一定为2); 如果有,代表已经符合条件:gcd(b1,b2,...,bn) > 1,直接输出0即可。(不需要对序列a进行任何操作。
两种方法
方法一 :贪心+数论
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std; const int maxn = 1e5 + ;
int a[maxn]; int GCD(int b1, int b2)
{
if (b2 == )
return b1;
return GCD(b2, b1%b2);
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE int n;
while (scanf("%d", &n) !=EOF) {
scanf("%d", &a[]);
int t=a[], cnt = ;
for (int i = ; i < n; i++) {
scanf("%d", &a[i]);
t = GCD(t, a[i]);
if (t > ) { cnt++; }
}
printf("YES\n");
if ( cnt == n- ) { printf("0\n"); } // all is even
else {
// scan two times;
int ans = ;
for (int i = ; i < n; i++) {
if (a[i]% && a[i+]% && i+ < n) { // two odd
ans += ;
a[i] = ;
a[i+] = ;
}
} for (int i = ; i < n; i++) {
if (i+ < n && (a[i]% && a[i+]% == )|| (a[i]% == && a[i+]%) ) { // one odd one even
ans += ;
a[i+] = ;
}
}
printf("%d\n", ans);
}
}
return ;
}
方法二:动态规划(参考网上的,dp是我的痛~ = =)
设:
dp[i][0]: 前i-1个数为偶数,第i个数为偶数的最少操作次数
dp[i][1]: 前i-1个数为偶数,第i个数为奇数的最少操作次数
如果第 i 个数是奇数,
dp[i][0] = min(dp[i-1][0]+2, dp[i-1][1]+1); dp[i][1] = min(dp[i-1][0], inf);
如果第 i 个数是偶数,
dp[i][0] = min(dp[i-1][0], dp[i-1][1]+2);
dp[i][1] = inf; 还有一个初始化的问题需要注意下:
dp[0][!(a[0]%2)] = inf; ——》 这个要细心体会下
假设序列中第一个数就是偶数,dp[0][0]= 0 dp[0][1]= inf
假设序列中第一个数就是奇数,dp[0][0]= inf dp[0][1]= 0
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std; const int inf = ;
const int maxn = 1e5 + ;
int a[maxn];
// dp[i][0]: 前i-1个数为偶数,第i个数为偶数的最少操作次数
// dp[i][1]: 前i-1个数为偶数,第i个数为奇数的最少操作次数
int dp[maxn][]; int GCD(int b1, int b2)
{
if (b2 == )
return b1;
return GCD(b2, b1%b2);
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE int n;
while (scanf("%d", &n) !=EOF) {
scanf("%d", &a[]);
int t=a[], cnt = ; for (int i = ; i < n; i++) {
scanf("%d", &a[i]);
t = GCD(t, a[i]);
if (t > ) { cnt++; }
}
printf("YES\n");
if ( cnt == n- ) { printf("0\n"); } // all 有公约数 else {
memset(dp, , sizeof(dp));
dp[][!(a[]%)] = inf; for (int i = ; i < n; i++) {
if (a[i]%) { // odd
dp[i][] = min(dp[i-][]+, dp[i-][]+);
dp[i][] = min(dp[i-][], inf);
}
else {
dp[i][] = min(dp[i-][], dp[i-][]+);
dp[i][] = inf; }
}
printf("%d\n", dp[n-][]);
}
}
return ;
}
codeforces 798C.Mike and gcd problem 解题报告的更多相关文章
- Codeforces 798C. Mike and gcd problem 模拟构造 数组gcd大于1
C. Mike and gcd problem time limit per test: 2 seconds memory limit per test: 256 megabytes input: s ...
- Codeforces 798C - Mike and gcd problem(贪心+数论)
题目链接:http://codeforces.com/problemset/problem/798/C 题意:给你n个数,a1,a2,....an.要使得gcd(a1,a2,....an)>1, ...
- codeforces 798c Mike And Gcd Problem
题意: 给出一个数列,现在有一种操作,可以任何一个a[i],用a[i] – a[i+1]和a[i]+a[i+1]替代a[i]和a[i+1]. 问现在需要最少多少次操作,使得整个数列的gcd大于1. 思 ...
- 【算法系列学习】codeforces C. Mike and gcd problem
C. Mike and gcd problem http://www.cnblogs.com/BBBob/p/6746721.html #include<iostream> #includ ...
- codeforces#410C Mike and gcd problem
题目:Mike and gcd problem 题意:给一个序列a1到an ,如果gcd(a1,a2,...an)≠1,给一种操作,可以使ai和ai+1分别变为(ai+ai+1)和(ai-ai+1); ...
- Codeforces Round #410 (Div. 2)C. Mike and gcd problem
题目连接:http://codeforces.com/contest/798/problem/C C. Mike and gcd problem time limit per test 2 secon ...
- CF798 C. Mike and gcd problem
/* CF798 C. Mike and gcd problem http://codeforces.com/contest/798/problem/C 数论 贪心 题意:如果一个数列的gcd值大于1 ...
- #410div2C. Mike and gcd problem
C. Mike and gcd problem time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- CodeForces 689E Mike and Geometry Problem (离散化+组合数)
Mike and Geometry Problem 题目链接: http://acm.hust.edu.cn/vjudge/contest/121333#problem/I Description M ...
随机推荐
- 巨蟒python全栈开发linux之cento8
1.复习路飞部署学习 2.mysql数据库远程访问 3.mysql主从复制 4.redis安全方式启动 5.redis数据类型 6.redis发布订阅 7.redis持久化 8.redis哨兵 9.r ...
- 全局enter回车键js
js实现敲回车键触发事件 document.onkeydown = function(e){ var ev = document.all ? window.event : e; ){ alert(&q ...
- Python3.6全栈开发实例[026]
27.文件a.txt内容:每一行内容分别为商品名字,价钱,个数.apple 10 3tesla 100000 1mac 3000 2lenovo 30000 3chicken 10 3通过代码,将其构 ...
- app开发学习需要经历哪些流程
app开发学习需要经历哪些流程?如何零基础入门app开发?以下是知乎热心开发者的经验总结,对学习app开发有很好的参考意义 1.如果没有编程基础的,学习基础知识的过程肯定是必须的.2.有了一些基础 ...
- MySQL的SQL MODE
SQL MODE:定义mysqld对约束等的响应行为: 查看当前模式: mysql> SHOW GLOBAL VARIABLES LIKE 'sql_mode'; 修改 ...
- 我的第三个Python小程序
99乘法表: # Author: fansik # Description: 99 times table # method 1 num1 = 0 num2 = 0 while num1 < 9 ...
- Python基础(7)_闭包函数、装饰器
一.闭包函数 闭包函数:1.函数内部定义函数,成为内部函数, 2.改内部函数包含对外部作用域,而不是对全局作用域名字的引用那么该内部函数成为闭包函数 #最简单的无参闭包函数 def func1() n ...
- Android 工具类 SharedPreferences 封装
SharedPreferences 是 Android 数据存储方式中的一种,特别适合用来存储少量的.格式简单的数据,比如应用程序的各种配置信息,如是否打开音效,是否开启震动等等. SharedPre ...
- iOS Xcode 8 快捷键 (注释 失效 处理)
在升级后,好用的VVDocumment 插件不能用了.(但是苹果这次内置了好多好用的插件,也有自己的注释功能了 AddDocumentation) 上网上有查到 传播很广泛的一条信息 "这个 ...
- flex datagrid 导出csv
public function exportToCSV(dataGrid:DataGrid):void { var dataProviderCollection:ArrayCollection = d ...