[gym102012C]Rikka with Consistency

time limit per test : 8.0 s
memory limit per test : 1024 MB

On the way to the Moscow, Rikka knows someone will replace her. Who is the guy? A devil to get in touch with her dark side, or an angel to rinse the shadow off her mind? However, Rikka knows that her successor has a special name, whose meaning in Chinese is Consistency. The process of replacement is so wonderful and sentimental, which is what you all must know.

Now, the only road from Beijing to Moscow is described as a broken line with n n segments in the X H X-H plane. The i-th segment connects the points ( i 1 , h i 1 ) (i−1,h_{i−1}) and ( i , h i ) (i,h_i) , and h 0 = h n = 0 h_0=h_n=0 are known. This figure is a topographic map showing the whole trip from Beijing to Moscow and its H H axis indicates the altitude. The distance of a path between two points is the length of the broken line between their corresponding points in the map.

At the outset of the trip, Rikka is in Beijing whose location in the X H X-H plane is ( 0 , 0 ) (0,0) ; Consistency, the guy who will replace Rikka, is in Moscow which is located at ( n , 0 ) (n,0) . Consistency always maintains consistent academic standards, a consistent life level, a consistent height of perspective and the altitude as what Rikka owns. This is why their heights are the same yesterday, today and forever.

Now Rikka wants you to calculate the minimum total distance they need (which is the total length of paths that Rikka and Consistency travel along). By the time that Rikka arrives in Moscow and Consistency arrives in Beijing as well, their replacement will be finished (and this is the ending which is also a new beginning).

Input

The input contains several test cases, and the first line contains a single integer T ( 1 T 500 ) T(1≤T≤500) , the number of test cases.

For each test case, the first line contains a single integer n ( 1 n 50 ) n(1≤n≤50) , the number of segments.
The second line contains ( n + 1 ) (n+1) integers h 0 , h 1 , , h n ( 0 h i 50 ) h_0,h_1,⋯,h_n (0≤h_i≤50) , satisfying h 0 = h n = 0 h_0=h_n=0 .The input guarantees that the paths for each test case always exist.

Output

For each test case, output a single line with a single number, the minimum total distance they need. Your answer is considered correct if its absolute or relative error does not exceed 1 0 9 10^{−9}
. Formally, let your answer be a a , and Rikka’s answer be b b . Your answer is considered correct if a b m a x ( 1 , b ) 1 0 9 |a−b|max(1,|b|)≤10^{−9} .

Example
Input

2
4
0 1 1 2 0
4
0 2 1 3 0

Output

12.128990204491960
22.313624568639947

题意:
给定 n + 1 n+1 个柱子,编号为 0 0 ~ n n h i h_i 表示第 i i 个柱子的高度,每辆个相邻的柱子之间,他们的顶上会有连线(两点之间的直的连线), h 0 = h n = 0 h_0=h_n=0 ,开始的时候柱子 0 0 上有一个人,要走到 n n ;同时柱子 n n 上有一个人,从 n n 走到 0 0 ,两个柱子之间的连接只有顶上的连线。这两个人每一时刻的高度都要相同。请问两个人都到达目的地的时候,两个人最少的走过路程总和是多少。

题解:
最短路
d i s [ x ] [ y ] [ z ] dis[x][y][z] 表示起点为0的人当前在 [ x , x + 1 ] [x,x+1] 段,起点为 n n 的人当前在 [ y , y + 1 ] [y,y+1] 段,高度为 z z 的最短路径。
每次转移的时候考虑相邻两个柱子高度相同的转移。
再考虑高度变化为 1 1 的转移。
可以预处理出所有响铃的柱子高度分别为 a , b a,b 时,高度变化为 1 1 的时候,单位高度 m p [ a ] [ b ] mp[a][b]

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
const double eps=1e-12;
const double INF=2000093000.443;
double SQR(double x){return x*x;}
int sgn(double x){
    if(-eps<x&&x<eps)return 0;
    else if(x<=-eps)return -1;
    else return 1;
}
struct point{
    int x,y,h;
    point(int _x,int _y,int _h){
        x=_x;
        y=_y;
        h=_h;
    }
    /*
    double dis_t(point B){
        return sqrt((x-B.x)*(x-B.x)+(y-B.y)*(y-B.y));
    }
    */
};
double dis[54][54][54],mp[64][64];
queue<point>q;
int n;
int h[54];
void work(int rik,int con,int hei,double val){
    //cout<<rik<<" "<<con<<" "<<hei<<" "<<val<<" "<<dis[rik][con][hei]<<endl;
    if(dis[rik][con][hei]>val){
        dis[rik][con][hei]=val;
        q.push(point(rik,con,hei));
    }
}
int w33ha(){
    scanf("%d",&n);
    for(int i=0;i<=n+1;i++){
        for(int j=0;j<=n+1;j++){
            for(int k=0;k<=51;k++){
                dis[i][j][k]=INF;
            }
        }
    }
    while(!q.empty())q.pop();
    for(int i=0;i<=n;i++)scanf("%d",&h[i]);
    dis[0][n][0]=0;
    q.push(point(0,n,0));
    while(!q.empty()){
        point now=q.front();q.pop();
        int r,c,hi;
        r=now.x;c=now.y;hi=now.h;
        if(r>0&&hi==h[r]){
            work(r-1,c,hi,(h[r]==h[r-1])+dis[r][c][hi]);
        }
        if(c>0&&hi==h[c]){
            work(r,c-1,hi,(h[c]==h[c-1])+dis[r][c][hi]);
        }
        if(r<n&&hi==h[r+1]){
            work(r+1,c,hi,(h[r]==h[r+1])+dis[r][c][hi]);
        }
        if(c<n&&hi==h[c+1]){
            work(r,c+1,hi,(h[c]==h[c+1])+dis[r][c][hi]);
        }
        if(c<n&&r<n){
            if(min(h[r],h[r+1])<=hi-1&&max(h[r],h[r+1])>=hi-1&&min(h[c],h[c+1])<=hi-1&&max(h[c],h[c+1])>=hi-1){
                work(r,c,hi-1,dis[r][c][hi]+mp[h[r]][h[r+1]]+mp[h[c]][h[c+1]]);
            }
            if(min(h[r],h[r+1])<=hi+1&&max(h[r],h[r+1])>=hi+1&&min(h[c],h[c+1])<=hi+1&&max(h[c],h[c+1])>=hi+1){
                work(r,c,hi+1,dis[r][c][hi]+mp[h[r]][h[r+1]]+mp[h[c]][h[c+1]]);
            }
        }
    }
    printf("%.10f\n",dis[n][0][0]);
    return 0;
}
void prework(){
    for(int i=0;i<=60;i++){
        for(int j=0;j<=60;j++){
            if(i!=j){
                mp[i][j]=sqrt(SQR(i-j)+1)/(1.0*abs(i-j));
            }
        }
    }
}
int main(){
    prework();
    int T;scanf("%d",&T);
    while(T--)w33ha();
    return 0;
}
发布了302 篇原创文章 · 获赞 19 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/dxyinme/article/details/100566153