码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 6205 card card card ( 思维 )

时间:2017-09-13 17:51:01      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:组复制   its   第一个   hdu   continue   一个   情况   mil   分享   

题意 : 给定两个序列 a 和 b ,保证 a 数列的和 == b数列的和,从头到尾考虑 (a[i] - b[i]) 的前缀和,直到前缀和为负数则无法进行下去,所得的便是a[1~i]的和,现在有一个操作,就是你可以将最前面的a[1] && b[1] 这两个数放到末尾去,问你最少经过多少次这样的操作能够使得去到的a[1~i]的的和是最大的

 

分析 : 发现因为有 a数列的和 == b数列的和,所以肯定有以某一个数开头使得将所有序列的数全部取完即 sum( a[1~末尾] ),我们先构造出 sub[i] = a[i] - b[i] 的序列,然后每一次选取一个正的sub[i] 作为开头来判断是否可行,如果在 i~k-1都可行,但是加上sub[k]就变得不可行,那么下一个开头就不是离 sub[i] 右边最近的一个正整数作为头,而是离 sub[k] 右边(当然最后一个元素的右边是第一个元素) 最近的一个正整数作为开头,为什么这样做呢?首先先如果按照第一种做法肯定是正确的,但是在时间上不是最优的,因为从 i~(k-1) 都是可行的,那么如果下一个开头的数还是在 i~(k-1) 这个序列里面考虑的话,那么下一次还是会在 k 这里停止,因为 sub[i] 是正数,细想就可以想明白了。模拟这个操作可以将数组复制一边粘到原数组末尾,但是这里我用了%操作,其实都一样。

 

技术分享
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
int n, a[maxn], b, sub[maxn];
inline int Scan()
{
    int res = 0, ch;
    bool flag = false;
    if((ch=getchar()) == -) flag = true;
    else if(ch>=0 && ch<=9) res = ch-0;
    while((ch=getchar())>=0 && ch<=9) res = res*10+ch-0;
    return flag?-res:res;
}
int main(void)
{
    while(~scanf("%d", &n)){
        for(int i=0; i<n; i++) a[i] = Scan();
        int negative = 0;
        for(int i=0; i<n; i++){
            b = Scan();
            sub[i] = a[i] - b;
            if(sub[i] < 0) negative++;
        }
        if(negative == n) { puts("0"); continue; }///全都是负数的情况
        int sum = 0, pos = 0;
        while(true){
            bool ok = true;
            while(sub[pos] < 0) pos++;///从当前位置开始找到右边第一个正数
            for(int i=pos, j=0; !(j!=0&&i==pos); j++, i=(i+1)%n){///开始累加前缀和sum,j的作用是辅助判断i是否已经第二次到达了pos这个位置,也就是pos是满足题意的!
                sum += sub[i];///累加前缀和
                if(sum < 0){///如果小于0,则在这里停止
                    ok = false;
                    pos = i;///记录一下当前位置
                    sum = 0;///重置前缀和
                    break;
                }
            }
            if(ok) break;
        }
        printf("%d\n", pos);
    }
    return 0;
}
View Code

 

瞎 : 沈阳网络赛的题,靠队友带飞,学习队友代码orz

HDU 6205 card card card ( 思维 )

标签:组复制   its   第一个   hdu   continue   一个   情况   mil   分享   

原文地址:http://www.cnblogs.com/Rubbishes/p/7516185.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!