题目意思:给出一个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. Sql注入_mysql权限入侵

    实验:测试不同数据库用户的操作权限 文件读写测试:load_file() ,into outfile 数据库用户账号密码存储在mysql.user下 Mysql最高权限用户root: Mysql普通权 ...

  2. Oracle中索引名称的唯一性

    数据库索引处理是遇到的一点问题,简单记录下 oracle的规定,在同一个SCHEMA下的对象是不能用相同的名字命名的,一般创建索引名用“表名_字段名”,这样能很快知道这个索引,是属于哪个表的. col ...

  3. 我的Android进阶之旅------>adbd cannot run as root in production builds 的解决方法

    今天用adb root命令时候,报了错误:adbd cannot run as root in production builds C:\Documents and Settings\Administ ...

  4. Java语言实现简单FTP软件------>FTP软件主界面的实现(四)

    首先看一下该软件的整体代码框架                        1.首先介绍程序的主入口FTPMain.java,采用了一个漂亮的外观风格 package com.oyp.ftp; im ...

  5. 基于nodejs的wiki系统

    jingo:        https://github.com/claudioc/jingo nodewiki:    https://github.com/nhoss2/nodewiki Tidd ...

  6. C#如何使用结构化异常处理

    Knowledge Base: Chinese (Simplified) 如何使用 Visual C# .NET 和 Visual C# 2005 中的结构化异常处理文章ID: 816157 最近更新 ...

  7. 解释*args和**kwargs的含义

    当我们不知道向函数传递多少参数时,比如我们向传递一个列表或元组,我们就使用*args def func(*args): for i in args: print(i) func(3,2,1,4,7) ...

  8. 顽石系列:Linux基础笔试

    顽石系列:Linux基础笔试 系统操作 压缩文件 扩展名 压缩程序 *.Z compress *.zip zip *.gz gzip *.bz2 bzip2 *.xz xz *.tar tar 程序打 ...

  9. SQL Server 简单事务学习

    select * from bank ) ) --打开一个事务 begin tran --定义临时变量 ; set @num = @num + @@error; --上一条语句出错次数 set @nu ...

  10. OC知识点(类方法,构造方法,组合模式,get,set方法,自动生成属性)

    1.类方法的优势 不用创建对象,节省了空间,直接用类名调用类方法,类方法为外界提供一个方便的调用接口.(特点:类方法以加号开头,不能使用自身的成员变量,它的调用不依赖成员变量) 2.构造方法(初始化成 ...