【题目来源】多校2014
【题目含义】给你n块石头,第 i 块石头的重量是 w i ,你每秒钟可以捡起一块石头(无论石头重量大小),但是有m次你不能捡石头,还要从手里扔下几块重量和大于k的石块,第 i次的时间是 t i ,求你捡起所有石块的时间
【题目分析】刚开始最这个题的时候我根本没看时间——才500ms啊!考坑!然后然后我就暴力求解了→_→,好不容易暴力结果正确了,却给了个TLE,改为用二分查询后又莫名其妙的给了RE,然后又是莫名其妙的MLE,三个多小时后才默默的得到了AC,啥也不说了,感觉今晚已经被坑爆了!
【AC代码】
#include <iostream>
#include <cstdio>
#include <cstring>
#define mem(x) memset((x),0,sizeof((x)))
#define inf 0x7fffffff
#define MAXN 10+100000
using namespace std;
int a[MAXN];
int b[MAXN];
int sum[MAXN];
int find(int x,int m){
if(x < 0)
return 0;
int l = 0;
int r = m;
int mid = -1;
while(l <= r){
mid = (l+r)/2;
if(x > sum[mid]){
l = mid+1;
}
else if(x < sum[mid]){
r = mid -1;
}
else return mid - 1;
}
return (l+r)/2;
}
int main()
{
freopen("in.txt","r",stdin);
mem(a);
mem(b);
int n,m,k;
while(scanf("%d%d%d",&n,&m,&k) != EOF){
mem(sum);
for(int i = 1; i <= n; i++){
scanf("%d",&a[i]);
sum[i] += sum[i-1] + a[i];
}
n++;
a[n] = inf;
sum[n] = inf;
for(int i = 1; i <= m; i++)
scanf("%d",&b[i]);
m++;
b[m] = inf;
int i,j;
long long t;
t = 0;
i = j = 1;
while(1){
if(t < b[j]-1 && i < n-1){
int xxx;
xxx = min((int)(b[j]-1-t),n-1-i);
t += xxx;
i += xxx;
}
if(i >= n-1){
if(j == 1){
++t;
}
if(t == b[j])
--t;
else
break;
}
if(i - 1 >= t)
--i;
i = find(sum[i] - k,n);
++t;
++j;
}
printf("%lld\n",t);
}
return 0;
}
我今晚提交的错误次数都已经把oj给刷屏了,为了记住此刻的耻辱吧,决定上传照片一张。
另外我也造了很多数据,能把这些数据都过了,基本就能AC了:
数据:
5 1 4
1 2 3 4 5
4
5 1 4
1 2 5 3 5
4
5 1 10
1 2 3 4 5
10
5 2 10
1 2 3 4 5
10 20
5 2 4
1 2 5 3 4
4 20
5 1 10
1 2 3 4 5
4
5 5 10
1 2 3 4 5
1 2 3 4 5
5 5 10
1 2 3 4 5
2 3 4 5 6
5 5 10
1 2 3 4 5
1 3 5 8 10
10 10 10
1 2 3 4 5 6 7 8 9 10
1 3 5 8 10 15 20 25 30 35
10 0 5
1 2 3 4 5 6 7 8 9 10
10 5 10
1 2 3 4 5 6 7 8 9 10
8 10 15 20 25
10 5 10
1 2 3 4 5 6 7 8 9 10
8 11 15 20 25
10 5 10
1 2 3 4 5 6 7 8 9 10
8 11 15 20 25
10 5 10
1 2 3 4 5 6 7 8 9 10
10 11 12 13 14
数据答案(一一对应):
8
7
5
5
7
9
10
11
15
46
10
19
19
19
24
希望我以后少遇到这种坑题,也少被这种坑题坑,同样,也希望大家如此。