http://vjudge.net/contest/view.action?cid=51327#problem/I
Description
Input
Output
Sample Input
input | output |
---|---|
5 1 4 1 2 3 4 5 4 |
8 |
Hint
地上有一定顺序的石子,每个石子的重量已知,现一人在地上捡石子,一秒捡起来一个,但是在第b[i],秒要从新丢下至少重量大于k的石子,重新捡。问最少需要多长时间才能把所有的石子权不捡起来。
解题思路:
本来想着模拟枚举一下就能过,写完才发现数据竟然是10^5, 于是又换了中二分写法==
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; int n,m,k; int s[100005],a[100005],b[100005]; int erfen(int x) { int l=0,r=n; int mid,ss=0;; while(l<=r) { mid=(l+r)/2; if(s[mid]<x) { ss=mid; l=mid+1; } else r=mid-1; } return ss; } int main() { while(~scanf("%d%d%d",&n,&m,&k)) { memset(a,0,sizeof(a)); memset(s,0,sizeof(s)); memset(b,0,sizeof(b)); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); s[i]=s[i-1]+a[i]; } for(int i=1;i<=m;i++) scanf("%d",&b[i]); b[++m]=2e9; int sum=0,p=0,temp; for(int i=1;i<=m;i++) { if(n-p<b[i]-sum) { sum+=n-p; break; } else { temp=p+b[i]-sum-1; sum+=b[i]-sum; p=erfen(s[temp]-k); } } printf("%d\n",sum); } return 0; }
#include <string.h> #include <stdio.h> #include <iostream> using namespace std; int n,m,k,a[100005]; int queue[100005],stack[100005]; int main() { while(~scanf("%d%d%d",&n,&m,&k)) { for(int i=0;i<n;i++) scanf("%d",&queue[i]); for(int i=0;i<m;i++) scanf("%d",&a[i]); int x=0; int y=0; int t=0; int xx=0; int count=a[0]; while(x!=n) { int flag=1; if(t+1!=count) { flag=0; stack[y++]=queue[x++],t++; } else { //printf("\n\n"); t++; int w=0; while(w<=k) { queue[--x]=stack[--y]; w+=stack[y]; if(y==0) break; } if(x<0) x=0,y=0; if(++xx<m) count=a[xx]; else count=-99999; } /*if(flag==0) printf("(%d,%d)\n",queue[x-1],stack[y-1]); else printf("(%d,%d)\n",queue[x],stack[y]);*/ } printf("%d\n",t); } return 0; } /*5 2 4 1 2 3 4 5 2 4 */