每日ACM小练习 2013年11月6日(水题)

FIR  NYOJ 7  街区最短路径问题

街区最短路径问题

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 4
描述
一个街区有很多住户,街区的街道只能为东西、南北两种方向。

住户只可以沿着街道行走。

各个街道之间的间隔相等。

用(x,y)来表示住户坐在的街区。

例如(4,20),表示用户在东西方向第4个街道,南北方向第20个街道。

现在要建一个邮局,使得各个住户到邮局的距离之和最少。

求现在这个邮局应该建在那个地方使得所有住户距离之和最小;

输入
第一行一个整数n<20,表示有n组测试数据,下面是n组数据;
每组第一行一个整数m<20,表示本组有m个住户,下面的m行每行有两个整数0<x,y<100,表示某个用户所在街区的坐标。
m行后是新一组的数据;
输出
每组数据输出到邮局最小的距离和,回车结束;

SEC POJ 1046 Color Me Less

Color Me Less
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 29111   Accepted: 14084

Description

A color reduction is a mapping from a set of discrete colors to a smaller one. The solution to this problem requires that you perform just such a mapping in a standard twenty-four bit RGB color space. The input consists of a target set of sixteen RGB color values, and a collection of arbitrary RGB colors to be mapped to their closest color in the target set. For our purposes, an RGB color is defined as an ordered triple (R,G,B) where each value of the triple is an integer from 0 to 255. The distance between two colors is defined as the Euclidean distance between two three-dimensional points. That is, given two colors (R1,G1,B1) and (R2,G2,B2), their distance D is given by the equation 

Input

The input is a list of RGB colors, one color per line, specified as three integers from 0 to 255 delimited by a single space. The first sixteen colors form the target set of colors to which the remaining colors will be mapped. The input is terminated by a line containing three -1 values.

Output

For each color to be mapped, output the color and its nearest color from the target set. 

If there are more than one color with the same smallest distance, please output the color given first in the color set.

解答及代码

Fir 两种方法

第一种:暴力枚举
/*****  简单ACM水题 ********/

/******** written by C_Shit_Hu ************/

////////////////街区最短路径问题///////////////

/****************************************************************************/
/* 
采用穷举法,找出最小距离之和并输出 
*/
/****************************************************************************/
#include <iostream>
#include <cmath>
using namespace std;

int abs(int a)  //求绝对值
{
	if(a<0)
		return -a;
	return a;	
}

// 函数体外定义初始化为0
int n,m;              // 记录测试数据组数和每组的元素个数
int x[20],y[20];      // 保存坐标,
int i, j, z, s;          // 循环变量
int xmax, ymax, xmin, ymin;        // 记录坐标中最大的x,y值
int youju_x,youju_y;  // 邮局坐标
int min_path,path_tmp;// 路径

int main()
{
/*
		freopen("in.txt","r",stdin);
		freopen("out.txt","w",stdout);
	*/
	cin >> n;  // 读入测试组数
	while(n--)
	{
		min_path=65530;
		path_tmp =0;
		cin >> m;   // 读入每组的测试个数
		s=m;
		while(m--)   // 循环读入坐标点
			cin >> x[m] >> y[m] ;
		xmax=x[0];ymax =y[0];
		for(i=1;i<s;i++)   //find the max Coordinate
		{
			if(xmax < x[i])
				xmax = x[i];
			if(ymax < y[i])
				ymax = y[i];
		}
		// 这一部分可以用sort函数排序,不过为避免原数组被破坏,需要新开空间

		for(i=1;i<=xmax;i++)  //穷举每个坐标,找出最小距离总和
			for(j=1;j<=ymax;j++)
			{
				path_tmp = 0;
				youju_x = i;
				youju_y = j;
				for(z=0;z<s;z++)
				{
					path_tmp += abs(youju_x-x[z]);
					path_tmp += abs(youju_y-y[z]);   // 横纵坐标之差的和即为二者的距离
				}
				if(min_path > path_tmp)
				{
			//		xmin = i;
			//		ymin = j;
					min_path=path_tmp;      // 找出最小的
				}
			}
			cout << min_path << endl;
			//cout << "X_Min:" << xmin <<"  Y_Min:" << ymin << endl;
	}
	return 0;
}

第二种:快速排序以及数学分析
/*****  简单ACM水题 ********/

/******** written by C_Shit_Hu ************/

////////////////街区最短路径问题///////////////

/****************************************************************************/
/* 
解题思路:
因为距离只计算x轴和Y轴距离之和而不是斜对角线距离,所以可以把x轴距离和y轴距离分开分析计算最短距离,彼此一定不会影响

以x轴横向点到其他点最短距离为例:
问题等价于在X轴有若干点中选取其中一点,使该点到其他点距离和最小
这个最短距离点一定是排在中间的那个点,比如有5个点,一定选择第3个点;如果有4个点,一定选择第2个点或者第3个点
(可以证明选择这两个点任意一个,结果一定相同)
y轴的一样。

选择中间点的反证法证明:
假设选择非中间点,并认为该点到其他点的距离和最小,大家可以在X轴上画画图算算,
一定还可以找到距离和比最小值还小一段距离的点(距离大小为假设最小点到中间点的距离),这和我们假设距离和最小条件矛盾,所以只能选中间点。
*/
/****************************************************************************/
#include <iostream>
#include <algorithm> 
using namespace std;

int n,m,i,x[20],y[20];

int main()
{
//reopen("in.txt","r",stdin);
//reopen("out.txt","w",stdout);

	cin >> n;
	while(n--)
	{
		int min_path=0 ;
		cin >> m;
		for(i=0; i!=m; i++)
			cin >> x[i] >> y[i];
		//将数组升序排序
		sort(x, x+m);
		sort(y, y+m);

		for(i=0;i<m/2;i++)   //find the min Coordinate
			min_path += x[m-i-1]-x[i]+ y[m-i-1] - y[i];
		cout << min_path<< endl;
		
	}
	return 1;
}



运行结果:

每日ACM小练习 2013年11月6日(水题)_第1张图片

第二题

#include <iostream>
#include <cstdio>
using namespace std;

// 定义目标颜色结构体,数组
struct color
{
    int R,G,B;
}map[16];


int main()
{
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
    int i;
    for(i=0;i<16;i++)
		cin >> map[i].R >> map[i].G >> map[i].B ;
    color c;   // 定义一个结构体变量
	// 当读入其他的颜色值且不是-1时
    while(cin >> c.R >> c.G >> c.B && (c.R != -1))
    {
		int index, min , d;
        index=0;  min=65535;
		// 枚举呀,大爷.....(只是求最短距离,不需要开方)
        for(i=0;i<16;i++)
        {
            d=(map[i].R-c.R)*(map[i].R-c.R) + 
			  (map[i].G-c.G)*(map[i].G-c.G) + 
			  (map[i].B-c.B)*(map[i].B-c.B);
			// 求出最近的那个,并标记最近的那个结构体数组下标
            if(min>d)
            {
                min=d;
                index=i;
            }
        } 
		cout << "(" << c.R << "," << c.G << "," << c.B << ")" << " maps to " 
			  << "(" << map[index].R << "," << map[index].G << "," << map[index].B  << ")" << endl;
    }
    return 0;
}

同样是暴力枚举(貌似只有这么做呢)

运行结果:

每日ACM小练习 2013年11月6日(水题)_第2张图片

先写实验报告了...
今天的ACM数论的晚上在做了。。。

【未完待续】........














你可能感兴趣的:(Algorithm,快速排序,ACM,cc++)