线型网络

线型网络

Time Limit:10s Memory Limit:1000k
Total Submit:7076 Accepted:1299
下载样例程序(PE)
下载样例程序(ELF)


Problem

有 N ( <=18 ) 台 PC 放在机房内,现在要求由你选定一台 PC,用共 N-1 条网线从这台机器开始一台

接一台地依次连接他们,最后接到哪个以及连接的顺序也是由你选定的,为了节省材料,网线都拉直。

求最少需要一次性购买多长的网线。(说白了,就是找出 N 的一个排列 P1 P2 P3 ..PN 然后 P1->P2 -> P3 -> ... -> PN

找出 |P1P2|+|P2P3|+...+|PN-1PN| 长度的最小值)

Input

该题含有多组测试数据,每组测试数据第一行 N ,下面 N 行,每行分别为机器的坐标(x,y) ( 实数 -100<=x,y<=100 )

Output

对于每组数据,输出最小值

Sample Input

3
0 0
1 1
1 -1

Sample Output

2.83

C解答各结果(严重超时)

#include <stdio.h>
#include <string.h>
#include <math.h>
struct Pos
{
    float x, y;
};
int main()
{
    int string_pos[11];
    int string_length, i, j, pos, find_again;
    float array[18][18], min, length;
    struct Pos pos_array[18];

    while(scanf("%d", &string_length)>0){
        if(string_length == 0) break;
        for(i = 0; i < string_length; i++){
            string_pos[i] = string_length - 1 - i;
            scanf("%f%f", &pos_array[i].x, &pos_array[i].y);
        }
        for(i = 0; i < string_length; i++){
            for(j = 0; j < string_length; j++){
                array[i][j] = array[j][i] = sqrt(
                    (pos_array[i].x - pos_array[j].x)*(pos_array[i].x - pos_array[j].x) +
                    (pos_array[i].y - pos_array[j].y)*(pos_array[i].y - pos_array[j].y));
            }
        }
        min = 10000;
        while(string_length > 1){
            length = 0;
            for(i = 0; i < string_length-1; i++) length += array[string_pos[i]][string_pos[i+1]];
            if(length < min) min = length;
            pos = 1;
            do{
                find_again = 0;
                string_pos[pos]++;
                if(string_pos[pos] == string_length) find_again = 1;
                if(!find_again){
                    do{
                        length = 0;
                        for(j = pos + 1; j < string_length; j++){
                            if(j < string_length - 1)
                                length += array[string_pos[j]][string_pos[j+1]];
                            if(length > min) goto again;
                            if(string_pos[pos] == string_pos[j]){
                                string_pos[pos] ++;
                                if(string_pos[pos] == string_length){
                                    find_again = 1;
                                    goto again;
                                }else break;
                            }
                        }
                        if(j == string_length) goto again;
                    }while(1);
                }
again:
                if(find_again){
                    pos++;
                    if(pos == string_length) goto bye;
                }
            }while(find_again);
            for(i = 0; i < string_length; i++){
                for(j = string_length - 1; j >= pos; j--){
                    if(string_pos[j] == i) break;
                }
                if(j < pos){
                    pos --;
                    string_pos[pos] = i;
                }
            }
        }
bye:
        printf("%.2f/n", min);
    }
    return 0;
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值