题目意思:给出一个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 解题报告的更多相关文章

  1. 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 ...

  2. Codeforces 798C - Mike and gcd problem(贪心+数论)

    题目链接:http://codeforces.com/problemset/problem/798/C 题意:给你n个数,a1,a2,....an.要使得gcd(a1,a2,....an)>1, ...

  3. 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. 思 ...

  4. 【算法系列学习】codeforces C. Mike and gcd problem

    C. Mike and gcd problem http://www.cnblogs.com/BBBob/p/6746721.html #include<iostream> #includ ...

  5. 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); ...

  6. 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 ...

  7. CF798 C. Mike and gcd problem

    /* CF798 C. Mike and gcd problem http://codeforces.com/contest/798/problem/C 数论 贪心 题意:如果一个数列的gcd值大于1 ...

  8. #410div2C. Mike and gcd problem

    C. Mike and gcd problem time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  9. CodeForces 689E Mike and Geometry Problem (离散化+组合数)

    Mike and Geometry Problem 题目链接: http://acm.hust.edu.cn/vjudge/contest/121333#problem/I Description M ...

随机推荐

  1. Encrypt your home directory

    w

  2. JFrame 居中显示

    场景:    在利用 JAVA  的 Swing 开发 C/S 架构 的前端界面 目的:    想让 JFrame 居中显示在整个 屏幕的正中位置 方法一:计算窗体的左上角坐标 JFrame fram ...

  3. python并发编程&协程

    0x01 前导 如何基于单线程来实现并发? 即只用一个主线程(可利用的cpu只有一个)情况下实现并发: 并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操 ...

  4. Linux下源码安装redis,编译安装

    1.下载redis源码 [root@localhost opt]# wget http://download.redis.io/releases/redis-4.0.10.tar.gz 2.解压缩 [ ...

  5. 关于主键(PRIMARY KEY)和自增(AUTO_INCREMENT)结合使用的知识点

    1.主键(PRIMARY KEY)和自增(AUTO_INCREMENT)同时使用两种写法:    a.主键(PRIMARY KEY)和自增(AUTO_INCREMENT)分两行写        创建一 ...

  6. Node.js的概念与应用

    转:http://blog.jobbole.com/100058/?utm_source=blog.jobbole.com&utm_medium=relatedPosts Node.js 是什 ...

  7. 剑指offer 面试55题

    面试55题: 题目:二叉树的深度 题:输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 解题思路: ①如果一棵树只有一个节点,它 ...

  8. zabbix监控Mariadb数据库

    1.介绍: zabbix自带的MySQL插件来监控mysql数据库,但是太过简陋,基本没有啥作用,所以需要做更详细的监控,而percona就有这个详细监控的模版以及脚本,正好拿过来用. percona ...

  9. iOS9 Search API 之 Spotlight

    iOS9以后 有三种api提供搜搜方式 加强引导用户关注 我们的app及相关内容的方式 NSUserActivity Web Markup  Core Spotlight 用法 前两种 实战操作性不够 ...

  10. Oracle常用的OCI函数

    一. Oracle oci工具包安装: $ORACLE_HOME\BIN:执行文件和help文件 $ORACLE_HOME\OCI\INCLUDE:头文件 $ORACLE_HOME\OCI\LIB\B ...