Flagstone
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
Submit Status
In the Qingshuihe Campus of UESTC, the most annoy problem to students are the flagstone path on the lawn. The designer seems so stupid that the flagstone path often make students step in the gap. Now a perfect step is wanted in order to not step in any gaps and step on every flagstone. The step length is required to be constant while the length of the flagstone and gap are given different. The problem is asking you to tell the minimum length of the perfect step. To simplify the question, the foot is considered to be a point and the very beginning is the fore edge of the first flagstone, which also means the first flagstone has already been stepped on.
Input
The first line of the input contains one integer T, which indicate the number of test cases. In each test case, the first line contains an integer N(2≤N≤105), indicating the number of flagstone. Following N lines, and each line is the length of one flagstone. And the following N−1 lines are the length of the gaps. All data is integer. All the length will be a positive integer, and the sum of them will fit in a 32bit signed integer.
Output
One line for each test case contains only one number indicating the answer. One real number indicating the perfect step length should be accurate to two digits after the radix point. If it is impossible to find out a perfect step, just output impossible !
Sample input and output
Sample Input Sample Output
2
2
10
20
5
3
10
20
5
5
1000
15.00
impossible
Hint
每个石板踏且仅踏一次
Source
电子科技大学第七届ACM程序设计大赛 初赛
解析:
每个石板踏且仅踏一次
对于第 i 块石板,一定是踏了 i - 1 步到达的。
设第 i 块石板的左界和右界离起点的距离L, R,可以确定步长必须在区间[L / (i - 1), R / (i - 1)]之内。
问题转化为求多个区间的交。如果交集为空,则答案为impossible,否则输出交区间的左界。
#include<stdio.h>
int a[100001];
int b[100001];
int main()
{
int t,p;
int n,i;
double h,l;
double hh,ll;
double s;
scanf("%d",&t);
for (p=1;p<=t;p++)
{
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf(“%d”,&a[i]);//n块石板
for (i=1;i<n;i++)
scanf(“%d”,&b[i]);//n-1个间隔
s=0;
l=a[1]+b[1];//第二块左边界
h=a[1]+b[1]+a[2];//第二块右边界
for (i=1;i<n;i++)
{
s=s+a[i]+b[i];
ll=s/(double)i;//第i块步长左区间
hh=(s+a[i+1])/(double)i;//第i块右区间
if (ll>l) l=ll;
if (hh<h) h=hh;//计算步长区间的交集
}
if (l<=h) printf(“%.2lf\n”,l);//交集存在
else printf("impossible\n");
}
return 0;
}
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <string>
#include <numeric>
#include <algorithm>
#include <functional>
#include <iterator>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <complex>
#include <ctime>
typedef long long LL;
const double pi = acos(-1.0);
const long long mod = 1e9 + 7;
using namespace std;
int a[100005],b[100005];
int main()
{
int T,N;
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
for(int i = 1; i <= N;i++)
scanf("%d",&a[i]);
for(int i = 1;i < N;i++)
scanf("%d",&b[i]);
double l,r,ll,rr,sum = 0;
l = a[1] + b[1];
r = l + a[2];
for(int i = 1;i < N;i++)
{
sum += a[i] + b[i];
ll = sum / i;
rr = (sum + a[i + 1]) / i;
l = max(ll,l);
r = min(rr,r);
}
if(l > r)
puts("impossible");
else
printf("%.2f\n",l);
}
return 0;
}