HDU 3272 Mission Impossible (几何,枚举)

Mission Impossible

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 417    Accepted Submission(s): 179


Problem Description
There are A, B, C, D four kinds of resources, A can be obtained at any point in the X-axis. B can be obtained at any point in the Y-axis. C and D each will only be able to achieve at a certain point. Giving the coordinates of C and D, the coordinates of your current location. Find the shortest path to obtain the four kinds of resources and go back.
 

Input
The first line contains the number T of test cases(T<=150). Each of the following T lines consists of six integers cx, cy, dx, dy, hx and hy. (cx, cy) is the coordinates of resource C, (dx, dy) is the coordinates of resource D, (hx, hy) is the coordinates of your current location.
All the numbers of the input are in the range [-1000, 1000].
 

Output
Your program should produce a single line for each test case containing the length of the shortest path. The answers should be rounded to two digits after the decimal point.
 

Sample Input
  
  
3 1 1 2 2 3 3 1 1 -1 -1 -1 -1 1 -1 1 1 -1 1
 

Sample Output
  
  
8.49 5.66 6.83

给出A,B,C三点坐标,D为X轴上任意一点,E为Y轴上任意一点,求从C点出发经过A,B,D,E最后回到C的最短距离。

因为D,E的位置是轴上任意的点,所以如果AB  AC  BC线段和两坐标轴有交点的话,就可以省掉额外的到D E的路程

对于都没有交点的情况,那么就需要找到最短路径了 

对于A-D-B这样一条路径,两点之间的直线距离是最短的  但是AB又和X轴无交点    这时,我们可以找到B点关于X轴的对称点b 

对于b点  Ab线段是一定会有与X轴的交点  而D点就是交点  而Ab线段就是A-D-B的最短路径


那么对于任意一点  该点到下一点的情况可以分为  直接到下一点  与X轴无交点时可以到下一点的X轴对称点  与Y轴无交点时到下一点与Y轴的对称点  与X,Y轴无交点时,到下一点相对X轴对称后相对Y轴的对称点

枚举所有情况即可


#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<map>
#define LL long long
const int INF=0x3f3f3f3f;
const  double eps=1e-10;
const double PI=acos(-1.0);
using namespace std;

struct node
{
    double x,y;
} e[10];

double minlen;
bool vis[10];

double Abs(double a)
{
    if(a<0) a=-a;
    return a;
}

double lenn(node a,node b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

bool cheakx(node a,node b)
{
    return a.y*b.y<=0;
}

bool cheaky(node a,node b)
{
    return a.x*b.x<=0;
}

void dfs(int i,int len,double sum,bool x,bool y)
{
    if(len==3)
    {
        x=x||cheakx(e[i],e[2]);
        y=y||cheaky(e[i],e[2]);
        if(x&&y)
        {
            minlen=min(minlen,sum+lenn(e[i],e[2]));
        }
        else if(!x&&!y)
        {
            if(!cheakx(e[i],e[2])&&!cheaky(e[i],e[2]))
            {
                e[i].x=-e[i].x;
                e[i].y=-e[i].y;
                minlen=min(minlen,sum+lenn(e[i],e[2]));
                e[i].x=-e[i].x;
                e[i].y=-e[i].y;
            }
            else if(!cheakx(e[i],e[2]))
            {

            e[i].y=-e[i].y;
            minlen=min(minlen,sum+lenn(e[i],e[2]));
            e[i].y=-e[i].y;
            }
            else if(!cheaky(e[i],e[2]))
            {
            e[i].x=-e[i].x;
            minlen=min(minlen,sum+lenn(e[i],e[2]));
            e[i].x=-e[i].x;

            }
            else minlen=min(minlen,sum+lenn(e[i],e[2]));
        }
        else if(!x)
        {
            if(!cheakx(e[i],e[2]))
            {e[i].y=-e[i].y;
            minlen=min(minlen,sum+lenn(e[i],e[2]));
            e[i].y=-e[i].y;
            }
            else minlen=min(minlen,sum+lenn(e[i],e[2]));
        }
        else
        {

            if(!cheaky(e[i],e[2]))
            {e[i].x=-e[i].x;
            minlen=min(minlen,sum+lenn(e[i],e[2]));
            e[i].x=-e[i].x;
            }
            else
            minlen=min(minlen,sum+lenn(e[i],e[2]));
        }


        return ;
    }

    for(int j=0; j<3; j++)
    {
        if(!vis[j])
        {
            vis[j]=true ;
            node no=e[j];
            dfs(j,len+1,sum+lenn(e[i],e[j]),x||cheakx(e[i],e[j]),y||cheaky(e[i],e[j]));
            if(!(cheakx(e[i],e[j])||x))
            {
                no=e[j];
                no.y=-e[j].y;
                dfs(j,len+1,sum+lenn(e[i],no),x||cheakx(e[i],no),y||cheaky(e[i],no));
            }

            if(!(cheaky(e[i],e[j])||y))
            {
                no=e[j];
                no.x=-e[j].x;
                dfs(j,len+1,sum+lenn(e[i],no),x||cheakx(e[i],no),y||cheaky(e[i],no));
            }

            if(!(cheakx(e[i],e[j])||x)&&!(cheaky(e[i],e[j])||y))
            {
                no=e[j];
                no.y=-e[j].y;
                no.x=-e[j].x;
                dfs(j,len+1,sum+lenn(e[i],no),x||cheakx(e[i],no),y||cheaky(e[i],no));
            }

            vis[j]=false ;
        }
    }
}

double init()
{
    minlen=1e8;
    memset(vis,false ,sizeof(vis));
    vis[2]=true ;
    dfs(2,1,0,0,0);
    return minlen;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        for(int i=0; i<3; i++) scanf("%lf%lf",&e[i].x,&e[i].y);
        printf("%.2lf\n",init());
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值