codeforces 798c

比赛的时候读错题+在电脑前时间很少(搞完ab之后就在实验室会宿舍的路上了orz)。。再加上自己构造能力很差。。妥妥的放过了一道c题orz。看来构造(数学yy)能力还得加强

题目:
http://codeforces.com/problemset/problem/798/C
题目大意:
给你一个有序的数,需要你将这个序列构造成一个gcd(a1,a2,a3..an) > 2的序列
有如下操作
[ ai , ai+1 ] -> [ ai+1 - ai , ai+1 + ai ]
该操作每次需要花费1个单位的操作次数

我们可以令gcd(x,y) 则有 -> gcd(x - y,x + y) = d
设有gcd(p,q) = 1,则有gcd(pd,qd) = d
有pd = x - y,qd = x + y
则2x = (p + q)d,2y = (q - p)d
该操作可以使公因子*1或者*2
所以,我们可以考虑一下奇偶的问题:
两个都是偶数,不需要操作
两个都是奇数,操作一次变成偶数
一个奇数一个偶数,操作一次变成两个都是奇数,再操作一次变成两个都是偶数

先预处理如果所有的gcd已经满足要求,如果不满足再进行操作
我们只需要贪心就好了,第一次将所有两两挨着的奇数都变成偶数
第二次肯定没有挨着的奇数了,就把一奇一偶操作两次变成偶数,答案就出来了orz。(果然我比较菜)

附上代码:

/*
@resources: codeforces798c
@date: 2017-4-25
@author: QuanQqqqq
@algorithm: 构造 greedy
*/

#include <bits/stdc++.h>

#define MAXN 100005

using namespace std;

int gcd(int a,int b){
    int c = a % b;
    while(c){
        a = b;
        b = c;
        c = a % b;
    }
    return b;
}

int main(){
    int n,tmp,num[MAXN];
    scanf("%d",&n);
    for(int i = 0;i < n;i++){
        scanf("%d",&num[i]);
    }
    int res = gcd(num[0],num[1]);
    for(int i = 2;i < n;i++){
        res = gcd(res,num[i]);
    }
    printf("YES\n");
    if(res > 2 || n == 1){
        printf("0\n");
        return 0;
    }
    int ans = 0;
    for(int i = 0;i < n;i++){
        if(num[i] & 1){
            if(num[i + 1] & 1 && i + 1 < n){
                ans++;
                tmp = num[i];
                num[i] -= num[i + 1];
                num[i + 1] += tmp;
                i++;
            }
        }
    }
    for(int i = 0;i < n;i++){
        if(num[i] & 1 || (i + 1 < n && (num[i + 1] & 1))){
            ans += 2;
            tmp = num[i]; 
            num[i] -= num[i + 1];
            num[i + 1] += tmp;
            tmp = num[i];
            num[i] -= num[i + 1];
            num[i + 1] += tmp;
            i++;
        }
    }
    printf("%d\n",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值