题目意思:给出一个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. php学习笔记8--半边引号引发的问题

    前段时间重装了系统,后来说是又要用php,就重新搭建了apache+php+mysql的环境,由于之前搭建过好多次,感觉很easy,很快就搭建完成,然后写了下面的常用的测试环境的代码: <?ph ...

  2. 巨蟒python全栈开发linux之centos6 第二篇

    1. .nginx负载均衡的实现 .准备三台机器,准备3台虚拟机,或者和俩同桌交流一下 192.168.226.128 是nginx资源服务器,返回页面的 192.168.226.129 用作ngin ...

  3. Shiro 页面权限标签

    http://www.cnblogs.com/jifeng/p/4500410.html  不整理了,直接看人家写好的

  4. JS 插件 fastclick.js 解决手机端click点击延迟

    FastClick 是一个简单,易于使用的JS库用于消除在移动浏览器上触发click事件与一个物理Tap(敲击)之间的300延迟. 对于非移动浏览器不启作用,禁用缩放标签. <meta name ...

  5. width: 50%; display:inline-flex;

    <style lang="less"> @import "../style/weui.wxss";   @wx-width: 750rpx; @wx ...

  6. Creating a Message Queue in PHP Without External Libraries

    w http://www.ebrueggeman.com/blog/creating-a-message-queue-in-php

  7. 如何搭建一个 Git 版本控制服务端?

    Gogs 下载和安装 https://github.com/gogits/gogs # 下载二进制压缩包 不检查服务器证书 root@cheungxiongwei:~# wget --no-check ...

  8. Python打印一个等边三角形

    如图所示: * *** ***** ******* ********* #想要几层就输入数字几, num = int(input('请输入一个奇数数字:')) for i in range(num,0 ...

  9. Android之四大组件、六大布局、五大存储

    [-] Android六大界面布局方式 1 LinearLayout线性布局 LinearLayout的常用XML属性及相关方法 LinearLayout子元素支持的常用XML属性及方法 2 Tabl ...

  10. boost之日期date_time

    date_time库使用的日期基于格里高利历,支持从1400-01-01到9999-12-31的日期. 空的构造函数会创建一个值为not_a_date_time的无效日期:顺序传入年月日值则创建一个对 ...