题目意思:给出一个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. iOS响应超出View范围点击事件

    // 在view中重写以下方法,其中self.button就是那个希望被触发点击事件的按钮 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent ...

  2. Oracle数据库用户及表空间操作

    //创建数据表空间 create tablespace test_data datafile '/u01/user_data.dbf' size 50m autoextend on next 50m ...

  3. java线程:Atomic(原子)

    .何谓Atomic? Atomic一词跟原子有点关系,后者曾被人认为是最小物质的单位.计算机中的Atomic是指不能分割成若干部分的意思.如果一段代码被认为是Atomic,则表示这段代码在执行过程中, ...

  4. jquery生成二维码图片

    1.插件介绍 jquery.qrcode.min.js插件是jq系列的基于jq,在引入该插件之前要先引入jq.能够在客户端生成矩阵二维码QRCode 的jquery插件 ,使用它可以很方便的在页面上生 ...

  5. python并发编程&IO模型

    一 IO模型介绍 为了更好地了解IO模型,可先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(n ...

  6. 详解mysql数据库的左连接、右连接、内连接的区别

    一般所说的左连接,外连接是指左外连接,右外连接.做个简单的测试你看吧. 先说左外连接和右外连接: SQL>select * from t1; ID NAME ---------- ------- ...

  7. SpringMVC 课纲

    SpringMVC 课纲 第一章 SpringMVC 架构 一个简单的 web 项目,校验器 SpringMVC 组件及相互关系 第二章 数据绑定 form标签库 第三章 Converter 和 Fo ...

  8. MC20模块教程目录

    MC20模块使用教程 为了阅读和修正方便,所有教程在线观看,请在有网络的环境下观看下面教程,谢谢! MC20模块教程在线目录 第一章:基础使用,使用电脑调试MC20的各项功能 1.1 使用电脑测试MC ...

  9. 神奇的Timer

    最近的一个项目有一些地方需要用到定时功能,在设计过程中,突然发现.net的Timer类居然还有很多我以前没有用过的功能,这里就跟大家分享一下 注:这里的Timer类特指System.Threading ...

  10. SourceTree的基本使用---基本介绍/本地开发

    转载自https://www.cnblogs.com/tian-xie/p/6264104.html 1. SourceTree是什么 拥有可视化界面的项目版本控制软件,适用于git项目管理 wind ...