Electric Fences

原创 2013年12月04日 11:23:20

题意:摘自NOCOW翻译(http://www.nocow.cn/index.php/Translate:USACO/fence3

描述

农夫约翰已经决定建造电网。他已经把他的农田围成一些奇怪的形状,现在必须找出安放电源的最佳位置。

对于每段电网都必须从电源拉出一条电线。电线可以穿过其他电网或者跨过其他电线。电线能够以任意角度铺设,从电源连接到一段电网的任意一点上(也就是,这段电网的端点上或者在其之间的任意一点上)。这里所说的“一段电网”指的是呈一条线段状的电网,并不是连在一起的几段电网。若几段电网连在一起,那么也要分别给这些电网提供电力。

已知所有的 F(1 <= F <= 150)段电网的位置(电网总是和坐标轴平行,并且端点的坐标总是整数,0 <= X,Y <= 100)。你的程序要计算连接电源和每段电网所需的电线的最小总长度,还有电源的最佳坐标。

电源的最佳坐标可能在农夫约翰的农田中的任何一个位置,并不一定是整数。

[编辑]格式

PROGRAM NAME: fence3

INPUT FORMAT

第一行包括 F ——电网的数量。 下面的 F 行每行包括两个 X,Y 对,表示这段电网的两个端点。

(ps:数据中有电网是点的情况,即 68 97 68 97,这貌似与题目叙述不符,请注意 //from Error)(路人甲:貌似照做就行了,不用管,。。。)

OUTPUT FORMAT

只有一行,输出三个浮点数,每个保留1位小数。假定你的电脑的输出库会正确地对小数进行四舍五入。

这三个数是:

电源最佳坐标的 X 值, 电源最佳坐标的 Y 值,和 需要的电线的总长度(要最小)。

[编辑]SAMPLE INPUT (file fence3.in)

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

[编辑]SAMPLE OUTPUT (file fence3.out)

1.0 1.6 3.7


解题思路:

  1. 直接0.01精度搜索必然会爆时间,所以需要逐步提高精度
  2. 首先以step = 10的精度搜索坐标(x, y),找到最小的那些坐标(min_x, min_y),那么全局最小的点的坐标(g_min_x, g_min_y)肯定满足:min_x - step <= g_min_x <= min_x + step,min_y - step <= g_min_y <= min_y + step,也就是以点(min_x, min_y)为中心,2 * step为边长的正方形中
  3. 下一步就是以step = 1的精度在2中得出的范围中搜索,然后逐步提高精度,一直到step = 0.01
  4. 求出step = 0.01中距离最小的点即可

代码

/*
ID: zc.rene1
LANG: C
PROG: fence3
 */

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

#define MAX 100
#define MAX_DISTANCE 9999999.0

int F;
double fences[150][4];
double global_min_distance = MAX_DISTANCE, global_min_x, global_min_y;

void GetInput(FILE *fin)
{
    int i, j;

    fscanf(fin, "%d", &F);
    for (i=0; i<F; i++)
    {
	for (j=0; j<4; j++)
	{
	    fscanf(fin, "%lf", &fences[i][j]);
	}
    }
}

double DeltaDistance(double x, double y, int index)
{
    double x1 = fences[index][0];
    double y1 = fences[index][1];
    double x2 = fences[index][2];
    double y2 = fences[index][3];

    double ret = 0.0, temp;

    if (x1 > x2)
    {
	temp = x1;
	x1 = x2;
	x2 = temp;
    }
    if (y1 > y2)
    {
	temp = y1;
	y1 = y2;
	y2 = temp;
    }

    if (x < x1)
    {
	ret += ((x1 - x) * (x1 - x));
    }
    if (x > x2)
    {
	ret += ((x - x2) * (x - x2));
    }

    if (y < y1)
    {
	ret += ((y1 - y) * (y1 - y));
    }
    if (y > y2)
    {
	ret += ((y - y2) * (y - y2));
    }

    return sqrt(ret);
}

double GetDistance(double x, double y)
{
    int i;
    double ret = 0.0;

    for (i=0; i<F; i++)
    {
	ret += DeltaDistance(x, y, i);
    }

    return ret;
}

void CalDistance(double min_x, double max_x, double min_y, double max_y, double step)
{
    double x, y, new_step;
    double temp_distance, temp_min_distance = MAX_DISTANCE; 
    double stack[10][2];
    int i, bottom = -1, top = -1;

    for (x=min_x; x<=max_x; x+=step)
    {
	for (y=min_y; y<=max_y; y+=step)
	{
	    temp_distance = GetDistance(x, y);
	    if (temp_distance < temp_min_distance)
	    {
		temp_min_distance = temp_distance;
		top = 0;
		stack[top][0] = x;
		stack[top][1] = y;
	    }
	    else if (temp_distance == temp_min_distance)
	    {
		top++;
		stack[top][0] = x;
		stack[top][1] = y;
	    }
	}
    }

    new_step = step / 10.0;

    if (new_step >= 0.01)
    {
	while (top > bottom)
	{
	    x = stack[top][0];
	    y = stack[top][1];
	    CalDistance(x - step, x + step, y - step, y + step, new_step);
	    top--;
	}
    }
    else
    {
	if (temp_min_distance < global_min_distance)
	{
	    for (i=bottom+1; i<=top; i++)
	    {
		global_min_distance = temp_min_distance;
		global_min_x = stack[i][0];
		global_min_y = stack[i][1];
	    }
	}
    }
}

int main(void)
{
    FILE *fin, *fout;

    fin = fopen("fence3.in", "r");
    fout = fopen("fence3.out", "w");

    GetInput(fin);
    CalDistance(0.0, 100.0, 0.0, 100.0, 10.0);
    fprintf(fout, "%.1lf %.1lf %.1lf\n", global_min_x, global_min_y, global_min_distance);

    return 0;
}







使用 electric-fence 调试内存越界

使用 electric-fence 调试内存越界 2012-12-14 16:40:53| 分类: linux使用 |举报|字号 订阅 在嵌入式上开发底层软件经常会遇见莫名其妙的问题,尤其是...
  • xiaocao9903
  • xiaocao9903
  • 2014年09月11日 10:41
  • 1345

Fences 2.1 - 高效实用的桌面图标栅栏分类管理软件神器 (桌面图标再多也不会乱)

如果你的桌面图标凌乱不堪,那么就要试试这款桌面图标整理工具 Fences 了。它可以用来分类和组织你桌面上的图标,并把不同的图标归类放置“收纳盒”(栅栏)当中,你还可以随意移动和拉伸这个栅栏的尺寸。有...
  • KuangYeYaZi
  • KuangYeYaZi
  • 2014年04月18日 20:48
  • 2437

教你申请Hurricane Electric公司免费dns服务

本文教你申请Hurricane Electric公司免费DNS服务 对于大多数站长来说,拥有一个安全,稳定,高效,解析服务器对于网站的体验也是必不可少的,有些用户的话一般都会选择DnsPod等,但对...
  • Sir_fish
  • Sir_fish
  • 2015年11月02日 20:18
  • 2114

【USACO题库】3.4.1 Closed Fences闭合的栅栏

题意平面上有按逆时针顺序排好的N个点,给你这些点的坐标。 首先要判断这N个点按顺序连边构成的是否是一个合法的多边形。 一个合法的多边形定义为多边形的边与边互不相交。 然后再给一个点的坐标,求这个...
  • lyd_7_29
  • lyd_7_29
  • 2015年10月09日 11:46
  • 513

解决 Windows 右键无法新建文件问题的方法

解决 Windows 下右键无法新建文件的方法。这两天被这个问题搞的非常头疼,还到处都找不到解决方法。这个症状大概就是,右键 → 新建,然后卡住,文件资源管理器崩溃。...
  • Fengyunkkx
  • Fengyunkkx
  • 2017年08月01日 15:22
  • 816

iOS开发- 添加地址从通讯录中选择添加(firstName,lastName真机为nil,模拟器正常)

如图所示,即为博主今天要说的功能,想必很多app都有出现,大家也见过类似的功能,网上的代码也是属于烂大街的东西,随便一搜就有一箩筐,这是博主的代码:在使用下面代码之前,需要先引入: #import ...
  • CodingFire
  • CodingFire
  • 2017年07月25日 09:48
  • 358

【NOIP2012模拟10.9】电费结算(electric)

DescriptionWZK最近靠租房发家致富了。作为WZK老同学的你也要租房,于是WZK决定不要房租,但是电费还得付。以下是用电价格:举个例子吧。如果你用电为10123千瓦时,那么要付2 * 100...
  • qq_34593871
  • qq_34593871
  • 2016年09月24日 15:19
  • 517

EPLAN Electric P8最常遇见的几个问题

1.为何在功能文本区(或者自由文本区域,备注区域)等输入文字时,会提示 “根据权限管理中的当前规定,不允许输入字典中没有的文本”?     在EPLAN 启动时,用户会提示选择"初学者""进阶者"...
  • yongan1006
  • yongan1006
  • 2015年09月15日 10:51
  • 9330

内存关卡/栅栏 ( Memory Barriers / Fences ) – 译

翻译自:Martin Thompson – Memory Barriers/Fences 在这篇文章里,我将讨论并发编程里最基础的技术–以内存关卡或栅栏著称,那让进程内的内存状态对其他进程可...
  • origin_lee
  • origin_lee
  • 2015年02月01日 14:40
  • 299

Memory Barriers/Fences(内存关卡/栅栏 —原文)

In this article I'll discuss the most fundamental technique in concurrent programming known as memor...
  • working_brain
  • working_brain
  • 2014年09月02日 10:47
  • 925
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Electric Fences
举报原因:
原因补充:

(最多只允许输入30个字)