#先看题目
题目描述
在一个月黑风高的暴风雨夜,Farmer John 的牛棚的屋顶、门被吹飞了 好在许多牛正在度假,所以牛棚没有住满。
牛棚一个紧挨着另一个被排成一行,牛就住在里面过夜。有些牛棚里有牛,有些没有。 所有的牛棚有相同的宽度。
自门遗失以后,Farmer John 必须尽快在牛棚之前竖立起新的木板。他的新木材供应商将会供应他任何他想要的长度,但是吝啬的供应商只能提供有限数目的木板。 Farmer John 想将他购买的木板总长度减到最少。
给出 m,s,c,表示木板最大的数目、牛棚的总数、牛的总数;以及每头牛所在牛棚的编号,请算出拦住所有有牛的牛棚所需木板的最小总长度。
输入格式
一行三个整数 m,s,c,意义如题目描述。
接下来 c 行,每行包含一个整数,表示牛所占的牛棚的编号。
输出格式
输出一行一个整数,表示所需木板的最小总长度。
输入输出样例
输入 #1
4 50 18 3 4 6 8 14 15 16 17 21 25 26 27 30 31 40 41 42 43
输出 #1
25
说明/提示
【数据范围】
对于 100% 的数据,1≤m≤50,1≤c≤s≤200。
USACO Training Section 1.3
题目链接https://www.luogu.com.cn/problem/P1209
#思路
真的很恶心
1,先算出每个有牛的牛棚和相邻的前一个的距离
2,快排每个距离
3,总牛棚数减 总木板数-1 的间隔(从后向前遍历)
第一版代码
#include<bits/stdc++.h>
using namespace std;
int s[205],st[205];
int main()
{
int a,b,c;
cin>>a>>b>>c;
int l=c-1,ans=b;
for(int i=1;i<=c;i++){
cin>>s[i];
}
ans=s[c]-s[1]+1;
for(int i=1;i<=c-1;i++){
st[i]=s[i+1]-s[i];
}
sort(st+1,st+c);
for(int i=1;i<=a-1;i++){
ans-=st[l]-1;
l--;
}
cout<<ans;
return 0;
}
只有50分 why?
接下来 c 行,每行包含一个整数,表示牛所占的牛棚的编号。
没说按顺序!
再加一个快排
第二版代码
#include<bits/stdc++.h>
using namespace std;
int s[205],st[205];
int main()
{
int a,b,c;
cin>>a>>b>>c;
int l=c-1,ans=b;
for(int i=1;i<=c;i++){
cin>>s[i];
}
sort(s+1,s+1+c);
ans=s[c]-s[1]+1;
for(int i=1;i<=c-1;i++){
st[i]=s[i+1]-s[i];
}
sort(st+1,st+c);
for(int i=1;i<=a-1;i++){
ans-=st[l]-1;
l--;
}
cout<<ans;
return 0;
}
80分why?
对于 100% 的数据,1≤m≤50,1≤c≤s≤200。
没说 m<c!
再加一个特判
#最后附上完整代码
#include<bits/stdc++.h>
using namespace std;
int s[205],st[205];
int main()
{
int a,b,c;
cin>>a>>b>>c;
int l=c-1,ans=b;
for(int i=1;i<=c;i++){
cin>>s[i];
}
if(a>c){
cout<<c;
return 0;
}
sort(s+1,s+1+c);
ans=s[c]-s[1]+1;
for(int i=1;i<=c-1;i++){
st[i]=s[i+1]-s[i];
}
sort(st+1,st+c);
for(int i=1;i<=a-1;i++){
ans-=st[l]-1;
l--;
}
cout<<ans;
return 0;
}