hdu6205card card card

来源:互联网 发布:一千个哈姆雷特 知乎 编辑:程序博客网 时间:2024/05/16 07:07

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6205

题目意思:有n堆牌起初按1~n的序列放置,每堆牌有两个参数a[i],b[i],要求从首堆依次向下翻牌,如果到某一堆出现,

∑a[i]小于∑b[i]的情况则停止取牌,并获得所有的已取牌(∑a[i])。另外允许你将首位的牌放在末尾,求在获得最多牌的情况下,此操作执行的最小次数。(题目给定:a[]的总和和b[]的总和相等)

题目思路:首先明确一个原则:经过操作,所有的牌都是可以取走的。可以这样理解:令sum[]=a[]-b[],假如到i位置,sum[i]<0,则剩余部分sum[n]-sum[i]>0,此时将前i位置都放到末尾就可全取完。由于是最少次数,代码就从头开始模拟。(思考了一下,求最多次数可以考虑对∑a[]的一半进行比较,有个啥抽屉原理~

题目代码:

#include<iostream>#include<cstdio>#include<cstring>#include<string>#define f(i,a,b) for(int i=a;i<b;i++)using namespace std;const int N=1e6+5;int a[N],sum[N];int main(){#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);#endifint n;while(~scanf("%d",&n)){f(i,0,n) scanf("%d",sum+i);f(i,0,n){scanf("%d",a+i);sum[i]-=a[i];}int s=0,t=0,res=0;f(i,0,n){s+=sum[i];t++;if(s<0) res+=t,t=0,s=0;}printf("%d\n",res);}return 0;}



原创粉丝点击