Description
给出两个长度为 n n 的序列,初始可以把 a,b a , b 序列的前几个数拿到序列后面去,之后开始从 a a 序列的第一个数字开始取数,只要拿的序列数字之和不小于对应的 b b 序列数字之和则所拿数字合法,问在保证可以拿到的数字之和最大的情况下,初始最少要拿几个数到后面去
Input
多组用例,每组用例首先输入一整数表示序列长度,之后输入两个长度为 n n 的序列
Output
对于每组用例,输出为使所拿数字之和最大初始需要移动的数字个数
Sample Input
5
4 6 2 8 4
1 5 7 9 2
Sample Output
4
Solution
把 a,b a , b 序列复制一遍,尺取,假设当前区间为 [l,r] [ l , r ] ,即表示要把前 l−1 l − 1 个数字拿到后面去,只要当前区间 a a 序列之和不小于序列之和 r r 就继续往后扩展,扩展后如果所拿数字之和大于已有最大值则更新答案,然后把移动到 r+1 r + 1 继续上述过程
Code
#include<cstdio>
using namespace std;
namespace fastIO
{
#define BUF_SIZE 100000
//fread -> read
bool IOerror=0;
inline char nc()
{
static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
if(p1==pend)
{
p1=buf;
pend=buf+fread(buf,1,BUF_SIZE,stdin);
if(pend==p1)
{
IOerror=1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch)
{
return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';
}
inline void read(int &x)
{
char ch;
while(blank(ch=nc()));
if(IOerror)return;
for(x=ch-'0';(ch=nc())>='0'&&ch<='9';x=x*10+ch-'0');
}
#undef BUF_SIZE
};
using namespace fastIO;
const int maxn=2000005;
int n,a[maxn],b[maxn];
int main()
{
while(1)
{
read(n);
if(IOerror)break;
for(int i=1;i<=n;i++)read(a[i]);
for(int i=1;i<=n;i++)
{
read(b[i]);
b[i]=a[i]-b[i];
}
for(int i=1;i<=n;i++)a[i+n]=a[i],b[i+n]=b[i];
n*=2;
int i=1,j,ans=0,temp,sum=0,num=0;
while(1)
{
sum=0,temp=0,j=i;
while(j<=n&&sum+b[j]>=0)sum+=b[j],temp+=a[j],j++;
if(temp>ans)ans=temp,num=i-1;
i=j+1;
if(i>n)break;
}
printf("%d\n",num);
}
return 0;
}