CSU-1839 Who Feels Lucky(数形结合)

来源:互联网 发布:32寸网络电视价格 编辑:程序博客网 时间:2024/06/05 22:51

1839: Who Feels Lucky

        Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: 54     Solved: 16    

Description

Fred, one of the smartest prisoners, really needs to escape from an underground prison. He managed to reach the outer area. He just needs to run from there directly to the exit door. Not that easy! Since this is the most advanced protected prison, there are full of traps to prevent the prisoners for escaping. Trap is working like magnetic. Fred will be stuck if he is in the trap area while it is active (he can just be on the edge of trap). Even worse, there are many traps along the way. 
Since each trap use a lot of energy to capture the escapers, it will just active in short period of time. Then become inactive in another short period of time before active again. This trap cycles continuously between active/inactive. He needs to start running immediately. All trap also start active first time at that time. 
You are going the write the program to find the slowest, constant speed that Fred can run to the exit door without being trapped. Note that Fred is moving in a straight line. 

Input

First line of input is an integer T (0 < T <= 10), representing number of test cases. 
For each test case, it start with a line with an integer N (0 < N <= 30), the number of traps. 
Following N lines contain each trap information which are in A B S1 S2 format where: 
A (0 < A < 32768) is an integer number of trap active time length (seconds). 
B (0 < B < 32768) is an integer number of trap inactive time length (seconds). 
S1 (0 < S1 < 32768) is an integer number of start position of trap (meters from starting point). 
S2 (0 < S1< S2 < 32768) is an integer number of end position of trap (meters from starting point). 

Output

Answer T lines containing answer for each case. Answer could be the speed (meters/seconds) in 4 decimal point format (rounded) or just the wordIMPOSSIBLE if there is no possible speed.

Sample Input

331 1 1 22 2 2 31 1 3 421 3 1 21 3 3 413 1 2 3

Sample Output

1.00000.5000IMPOSSIBLE

题解:画出t-s图可以看出来,设K为第n个陷阱最多能循环的次数,那么(k(a+b)-b)/s1=k(a+b)/s2,

即k=b*s2/((a+b)(s2-s1))

设速度为v,那么t-s图中直线的斜率为1/v,要使速度最慢,那么就要取斜率最大的直线,找到第n个陷阱K取最大值时斜率的边界值[L,R],再往前面的陷阱依次递推,不断压缩区间,找到满足条件的R

123123123

#include<cstdio>#include<algorithm>#include<string.h>#include<iostream>#define fuck(x) cout<<"["<<x<<"]"<<endlusing namespace std;const int MX = 35;const double eps=1e-6;int a[MX],b[MX],tot[MX],s1[MX],s2[MX];double L,R;double get_L(int i,int k){return 1.0*(k*tot[i]-b[i])/s1[i];}double get_R(int i,int k){return 1.0*k*tot[i]/s2[i];}int get_K(int i,double t,bool &flag){    int cnt=(int)t/tot[i];    if (cnt*tot[i]==t) cnt--;    flag=cnt*tot[i]+a[i]>t?0:1;    return ++cnt;}bool check(int i){    bool flag1,flag2;    double l,r;    int maxK=get_K(i,R*s2[i],flag1);    int minK=get_K(i,L*s1[i],flag2);    if (maxK<minK||maxK==minK&&!flag1&&!flag2) return 0;    for (int k=maxK;k>=minK;k--){        r=get_R(i,k);        l=get_L(i,k);        if(r<L||l>R) continue;        R=min(R,r);        L=max(L,l);        return 1;    }    return 0;}int main(){    //freopen("in.txt","r",stdin);    int n,T;    scanf("%d",&T);    while(T--){        scanf("%d",&n);        for(int i=1;i<=n;i++) {            scanf("%d%d%d%d",&a[i],&b[i],&s1[i],&s2[i]);            tot[i]=a[i]+b[i];        }        int flag=0,i;        int K=b[n]*s2[n]/((s2[n]-s1[n])*tot[n]);        for(int k=K;k>0;k--){            L=get_L(n,k);R=get_R(n,k);            for(i=1;i<=n;i++) if(!check(i)) break;            if(i==n+1){                flag=1;                break;            }        }        if(!flag) printf("IMPOSSIBLE\n");        else printf("%.4lf\n",1.0/R);    }    return 0;}


0 0