这个星期忙着补笔记和写论文,在最近两天才看了看书,补了两道例题。
1433:【例题1】愤怒的牛
【题目描述】
农夫 John 建造了一座很长的畜栏,它包括N(2≤N≤100,000)个隔间,这些小隔间依次编号为x1,...,xN(0≤xi≤1,000,000,000). 但是,John的C(2≤C≤N)头牛们并不喜欢这种布局,而且几头牛放在一个隔间里,他们就要发生争斗。为了不让牛互相伤害。John决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是什么呢
【输入】
第一行:空格分隔的两个整数NN和CC;
第二行---第N+1行:i+1行指出了xi的位置。
【输出】
一个整数,最大的最小值。
【输入样例】
5 3
1 2 8 4 9
【输出样例】
3
【提示】
把牛放在1,4,8这样最小距离是3。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define M 1000010
#define ll long long
#define Mid (l+r+1)/2
int l, r, mid;
int n, c;
int a[M];
inline bool check(int m)
{
int sum = a[1] + m;
int cnt = 1;
for(int i = 2; i <= n; i++) {
if(a[i] >= sum) cnt++, sum = a[i] + m;
}
return cnt >= c;
}
int main() {
scanf("%d%d", &n, &c);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
r = 10000000, l = 0;
sort(a+1, a+n+1);
while(l < r) {//二分答案
mid = Mid;
if(check(mid)) l = mid;
else r = mid - 1;
}
printf("%d\n", l);
return 0;
}
1434:【例题2】Best Cow Fences
【题目描述】
给定一个长度为n的正整数序列A。求一个平均数最大的,长度不小于L的子序列。
【输入】
第一行,n和L;
n个正整数,表示A。
【输出】
一个整数,表示答案的1000倍(不用四舍五入,直接输出)。
【输入样例】
10 6
6 4 2 10 3 8 5 9 4 1
【输出样例】
6500
【提示】
n ≤ 100000
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define M 10000100
#define ex 1e-5
double l = 100000.0, r = -10000.0, mid;
int n, L;
double a[M], sum[M];
inline bool check(double ans)
{
double sum1, sum2, maxx;
sum1 = sum[L-1] - (L-1) * ans;
for(int i = L; i <= n; i++) {
sum2 = sum[i] - sum[i - L] - L * ans;
sum1 = sum1 + a[i] - ans;
sum1 = max(sum1, sum2);
if(sum1 > -ex) return true;
}
return false;
}
int main() {
scanf("%d%d", &n, &L);
for(int i = 1; i <= n; i++) {
scanf("%lf", &a[i]);
sum[i] = sum[i-1] + a[i];
l = min(l, a[i]), r = max(r, a[i]);
}
while(r - l > ex) {
mid = (l + r)/2;
if(check(mid)) l = mid;
else r = mid;
}
int ans = (int)(r * 1000);
printf("%d", ans);
return 0;
}
1435:【例题3】曲线
【题目描述】
明明做作业的时候遇到了nn个二次函数Si(x)=ax2+bx+c,他突发奇想设计了一个新的函数F(x)=max(Si(x)), i=1,2...n。
明明现在想求这个函数在[0,10000,1000]的最小值,要求精确到小数点后四位四舍五入。
【输入】
输入包含TT 组数据 (T<10T<10) ,每组第一行一个整数 n(n≤10000) ,之后nn行,每行3个整数a(0≤a≤100),b(|b|≤5000),c(|c|≤5000),用来表示每个二次函数的3个系数,注意二次函数有可能退化成一次。
【输出】
每组数据一个输出,表示新函数F(x)的在区间[0,10000,1000]上的最小值。精确到小数点后四位,四舍五入。
【输入样例】
2
1
2 0 0
2
2 0 0
2 -4 2
【输出样例】
0.0000
0.5000
【提示】
【数据范围】
T<10,n≤10000,0≤a≤100,|b|≤5000,|c|≤5000T<10
前50%数据,n≤100。
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<map>
#include<algorithm>
#include<stack>
using namespace std;
#define ll long long
double cat[200001][3],sum[200001];
double a,b,c;
double Sx(double x,int n)
{
double k=-1e10;
for(int i=1;i<=n;i++)
k=max(k,cat[i][0]*x*x+cat[i][1]*x+cat[i][2]);
return k;
}
int main()
{
ios::sync_with_stdio(false);
int n;
cin>>n;
while(n--)
{
int gr;
cin>>gr;
double l=0,r=1000,exp=1e-11;
for(int i=1;i<=gr;i++)
for(int j=0;j<3;j++)
cin>>cat[i][j];
while(r-l>exp)
{
double mid=(l+r)/2;
double midmid=(mid+r)/2;
if(Sx(mid,gr)>=Sx(midmid,gr))l=mid;
else r=midmid;
}
cout<<fixed<<setprecision(4)<<Sx(r,gr)<<endl;
}
}