昨天在poj 上面做了一道贪心的题目,过了一个下午也没能ac。还是今天早上才发现对题目的理解有一些错误,改完之后就ac了。
题目大一是这样的:从农夫家里到城镇之间有一条路,在下雨之后,出现了许多长短不一的水坑。农夫有一些固定长度的木板,可以覆盖这些水坑。如果木板长度大于水坑长度,超出的部分恰好在下一个水坑的区间内的话,就能用于覆盖下一个水坑,如果没有的话就忽略不计。现在第一行输入水坑数目和木板长度。接下来每行输入两个数,表示每个木板起始点和终点。我们需要输出的是每组样例至少需要多少个木板。
解题思路是:
先以区间的起始点对区间进行行从大到小的排序,在对区间进行操作。三种情况,详情见代码。
ac代码是:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
struct pe
{
int s;
int e;
}q[1000010];
bool cmp(pe a, pe b)
{
return a.s < b.s;
}
int main()
{
int n, l;
while(~scanf("%d%d", &n, &l)){
for(int i = 1; i<=n; i++){
scanf("%d%d", &q[i].s, &q[i].e);
}
sort(q+1, q+n+1, cmp);
int cnt = 0;
int x = q[1].s;
for(int i = 1; i<=n; i++){
if(x>q[i].s && x<=q[i].e){
while(x < q[i].e){
x = x+l;
cnt++;
}
}
else if(x >= q[i].e)
continue;
else if(x <= q[i].s){
x = q[i].s;
while(x < q[i].e){
x = x + l;
cnt++;
}
}
}
printf("%d\n", cnt);
}
return 0;
}
我之前一直就纠结wa很多次的代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
struct pe
{
long long s;
long long e;
}q[1000010];
bool cmp(pe a, pe b)
{
return a.s < b.s;
}
int main()
{
long long n, l;
while(~scanf("%I64d%I64d", &n, &l)){
for(int i = 1; i<=n; i++){
scanf("%I64d%I64d", &q[i].s, &q[i].e);
}
sort(q+1, q+n+1, cmp);
long long cnt = 0, lef = 0;
long long tmp;
for(int i = 1; i<n; i++){
if(q[i].e+1 != q[i+1].s){
tmp = (q[i].e-q[i].s) + lef;
if(tmp%l == 0) cnt = cnt+tmp/l;
else cnt = cnt+tmp/l+1;
lef = 0;
}
else{
tmp = (q[i].e-q[i].s)+lef;
cnt = cnt+tmp/l;
if(tmp%l != 0)
lef = tmp%l+1;
else lef = tmp%l;
}
}
tmp = (q[n].e-q[n].s) + lef;
if(tmp%l == 0) cnt = cnt+tmp/l;
else cnt = cnt+tmp/l+1;
printf("%I64d\n", cnt);
}
return 0;
}
一直没有ac的原因是题目意思的理解有点错误,我以为只有上一个区间的结束与下一个区间的开始相邻时才有可能出现上一个木板的剩余来覆盖下一个区间,其实是只要木板足够长就有可能出现这样的情况。