历届试题 邮局  
时间限制:1.0s   内存限制:256.0MB
    
问题描述
  C村住着n户村民,由于交通闭塞,C村的村民只能通过信件与外界交流。为了方便村民们发信,C村打算在C村建设k个邮局,这样每户村民可以去离自己家最近的邮局发信。



  现在给出了m个备选的邮局,请从中选出k个来,使得村民到自己家最近的邮局的距离和最小。其中两点之间的距离定义为两点之间的直线距离。
输入格式
  输入的第一行包含三个整数n, m, k,分别表示村民的户数、备选的邮局数和要建的邮局数。

  接下来n行,每行两个整数x, y,依次表示每户村民家的坐标。

  接下来m行,每行包含两个整数x, y,依次表示每个备选邮局的坐标。

  在输入中,村民和村民、村民和邮局、邮局和邮局的坐标可能相同,但你应把它们看成不同的村民或邮局。
输出格式
  输出一行,包含k个整数,从小到大依次表示你选择的备选邮局编号。(备选邮局按输入顺序由1到m编号)
样例输入
5 4 2

0 0

2 0

3 1

3 3

1 1

0 1

1 0

2 1

3 2
样例输出
2 4
数据规模和约定
  对于30%的数据,1<=n<=10,1<=m<=10,1<=k<=5;

  对于60%的数据,1<=m<=20;

  对于100%的数据,1<=n<=50,1<=m<=25,1<=k<=10。

感觉这道题还是很不错的,刚开始没怎么看数据量,写的代码超时了

超时思路:m个备用邮局,建k个,如果用1,0表示建跟不建,那么数组中就有k个1,m-k个0,所以全排列之后就是每一个方案,然后计算出每一组方案的话费,之后取最优花费,但是有的数据比较大,比如50,如果有10个邮局,那么方案就有很多很多,组合数公式算下来肯定崩,但是这个思路对于小的数据应该还是可以的,先上超时代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
struct node
{
double x,y;
}a[60],b[60];
int n,m,k,s[60],num[60];
double dis(int x,int y)
{
return sqrt((a[x].x-b[y].x)*(a[x].x-b[y].x)+(a[x].y-b[y].y)*(a[x].y-b[y].y));
}
double dfs()
{
double sum=0;
for(int i=0;i<n;i++)
{
double val=INF;
for(int j=0;j<m;j++)
{
if(s[j])
{
double d=dis(i,j);
val=min(val,d);
}
}
sum+=val;
}
return sum;
}
int main()
{
while(cin>>n>>m>>k)
{
memset(s,0,sizeof(s));
for(int i=0;i<n;i++)
cin>>a[i].x>>a[i].y;
for(int i=0;i<m;i++)
cin>>b[i].x>>b[i].y;
for(int i=0;i<k;i++)
s[i]=1;
int cnt;
double ans=INF;
do{
double si=dfs();
if(ans>si)
{
ans=si;
memset(num,0,sizeof(num));
cnt=0;
for(int i=0;i<m;i++)
if(s[i])
num[cnt++]=i;
}
}while(prev_permutation(s,s+m));
for(int i=0;i<k-1;i++)
printf("%d ",num[i]+1);
printf("%d\n",num[k-1]+1);
}
return 0;
}
</pre>AC思路(dfs+剪枝):dfs最重要的就是建立搜索树,这里每个点都有两种状态,如果直接暴力时间肯定很长,所以需要加上剪枝,我们可以将村子的住户还有备用邮局看作是两个集合,就像普利姆的思路一样,总的思路就是更新最短距离数组,我们先将所有的点全部连接在第一个备用邮局,也可以不连第一个,毕竟每个点有两种状态,如果第二个备用邮局到住户的距离足以更新最短距离数组,那就更新之后寻找下一个邮局,如果不足以更新最短距离数组,我们就直接放弃这个点,显然他是没有用的,找到k个邮局之后就判定一下话费,是否更短,如果是,更新序号数组
#include<iostream>
#include<stdlib.h>
#include<math.h>
using namespace std;
int n,m,k,j,c[55][2],y[27][2],d[12],f1,f2,f[55]={0};
float yc[27][55],s=1000000000;
int dfs(int t,int i,int o[12],float w[55],float sum)
{//t±íʾѰÕҵĵÚi¸öÓʾ֣¬t±íʾ±¸ÓÃÓʾֵıàºÅ
if(i<=m+1)
{
if(t==k)//ÕÒµ½ÁËk¸öÓʾ֣¬²¢ÇÒÏûºÄ¸üµÍ
{
if(sum<s)
{
s=sum;
for(j=0;j<k;j++)
d[j]=o[j];
}
}
else if(i<=m&&t<k)
{
float ww[55];//´æ´¢×î¶Ì¾àÀë
for(j=1;j<=n;j++)
ww[j]=w[j];//×î¶Ì¾àÀë¸´ÖÆ£¬Ã¿Ò»²½¶¼Òª½øÐÐ
dfs(t,i+1,o,w,sum);//Ò»¸öµãÓÐÁ½ÖÖ״̬£¬Õâ¸öÊDz»½¨Óʾֵģ¬
//½øÐÐÁËÕâÒ»²½£¬i²»²ÎÓë¸üÐÂ
f1=1,f2=0;//ÅжÏiÊÇ·ñ¿ÉÒÔʹÓÃ
if(!f[i])
{
o[t]=i;
if(t>0)
{
f2=1;//Èç¹ûi²»ÊǵÚ0¸öµã
for(j=1;j<=n;j++)
{
if(ww[j]>yc[i][j])
{
sum=sum-ww[j]+yc[i][j];//sum´¢´æ×ܵľàÀë
ww[j]=yc[i][j];
f1=0;//ww±»¸üеıê¼Ç
}
}
}
else
{
for(j=1;j<=n;j++)
{
sum+=yc[i][j];//¸Õ¿ªÊ¼Ê±È«²¿Á¬ÔÚµÚ1¸öµã¡£Ö®ºó¸üÐÂ
ww[j]=w[j]=yc[i][j];
}
}
if(f1&&f2)//¼ôÖ¦
{
f[i]=1;//²»ÊǵÚ0¸öµãÇÒ²»ÄܲÎÓë¸üÐÂ
dfs(t,i+1,o,w,sum);//Èç¹ûµÚi¸öÓʾֵ½ÆäËûn¸öµãµÄ¾àÀë¶¼±ÈwwÖеĴó£¬iÉáÆú
}
else
dfs(t+1,i+1,o,ww,sum);//µÚi¸öµã¿ÉÒÔ¸üÐÂww¾ÍʹÓøõã
}
}
}
}
int main()
{
int i,j,o[12];
float w[55],ww[55];
cin>>n>>m>>k;
for(i=1;i<=n;i++)
cin>>c[i][0]>>c[i][1];
for(i=1;i<=m;i++)
{
cin>>y[i][0]>>y[i][1];
for(j=1;j<=n;j++)
yc[i][j]=sqrt((c[j][0]-y[i][0])*(c[j][0]-y[i][0])+(c[j][1]-y[i][1])*(c[j][1]-y[i][1]));
}
dfs(0,1,o,w,0);
for(i=0;i<k;i++)
cout<<d[i]<<" ";
return 0;
}


历届试题 邮局(dfs+剪枝)的更多相关文章

  1. 算法笔记_178:历届试题 邮局(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 C村住着n户村民,由于交通闭塞,C村的村民只能通过信件与外界交流.为了方便村民们发信,C村打算在C村建设k个邮局,这样每户村民可以去离自己 ...

  2. Java实现 蓝桥杯 历届试题 邮局

    问题描述 C村住着n户村民,由于交通闭塞,C村的村民只能通过信件与外界交流.为了方便村民们发信,C村打算在C村建设k个邮局,这样每户村民可以去离自己家最近的邮局发信. 现在给出了m个备选的邮局,请从中 ...

  3. 蓝桥杯练习系统历届试题 带分数 dfs

    问题描述 100 可以表示为带分数的形式:100 = 3 + 69258 / 714. 还可以表示为:100 = 82 + 3546 / 197. 注意特征:带分数中,数字1~9分别出现且只出现一次( ...

  4. 蓝桥杯  历届试题 剪格子  dfs

    历届试题 剪格子 时间限制:1.0s   内存限制:256.0MB 问题描述 如下图所示,3 x 3 的格子中填写了一些整数. +--*--+--+ |10* 1|52| +--****--+ |20 ...

  5. 蓝桥杯  历届试题 幸运数  dfs

    历届试题 幸运数 时间限制:1.0s   内存限制:256.0MB 问题描述 幸运数是波兰数学家乌拉姆命名的.它采用与生成素数类似的"筛法"生成 . 首先从1开始写出自然数1,2, ...

  6. 蓝桥杯 历届试题 剪格子(dfs搜索)

    历届试题 剪格子 时间限制:1.0s   内存限制:256.0MB 问题描述 如下图所示,3 x 3 的格子中填写了一些整数. +--*--+--+ |* || +--****--+ ||* | ** ...

  7. 蓝桥杯-历届试题 剪格子(dfs)

    历届试题 剪格子   时间限制:1.0s   内存限制:256.0MB        问题描述 如下图所示,3 x 3 的格子中填写了一些整数. +--*--+--+|10* 1|52|+--**** ...

  8. 历届试题 危险系数-(dfs+记录路径)

     历届试题 危险系数   问题描述 抗日战争时期,冀中平原的地道战曾发挥重要作用. 地道的多个站点间有通道连接,形成了庞大的网络.但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系. 我 ...

  9. 蓝桥杯历届试题 地宫取宝 dp or 记忆化搜索

    问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能向右或向下行走. 走 ...

随机推荐

  1. JS——滚动条

    1.核心思想与之前的拖拽盒子是一样的 2.完全将鼠标在盒子中的坐标给滚动条是错的,因为这样会使滚动条顶部立刻瞬间移动到鼠标位置 3.必须在鼠标按下事件时记住鼠标在滚动条内部的坐标,再将鼠标在盒子中的坐 ...

  2. CSS——img

    img标签初始化:在低版本的ie浏览器会自带边框,所以建议border:0px.

  3. jsp 文件下载

    有的时候一个模板的下载,这种简单的下载服务端已存在文件功能,就可以方便的通过jsp文件下载的方式来轻松实现. //jsp 页面 js /** * 导出角色 */ function exportRole ...

  4. GCD & Operation queues & Thread

    One of the technologies for starting tasks asynchronously is Grand Central Dispatch (GCD). This tech ...

  5. CAD在网页绘一个直线,得到直线id,再调该得到直线对象,然写扩展数据

    IMxDrawDatabase::ObjectIdToObject 实体id返回实体对象. 参数 说明 [in] LONGLONG lId 实体id JS代码,中绘一个直线,得到直线id,再调该得到直 ...

  6. 00 python基础知识

    ''' ''' print('hello world!') ''' 变量 ''' # 变量的:‘tank’,会在内存中产生一份内存地址 #变量名:相当于一个门牌号,用于与变量进行绑定 # = :用来把 ...

  7. 微智魔盒APP开发程序解析

    微智魔盒系统开发找崔经理l88Z.6ZZ685l.微智魔盒app开发.微智魔盒商城开发.微智魔盒软件开发,微智魔盒模式开发,微智魔盒源码开发.微智魔盒开发. @Override publicvoidr ...

  8. Self-Attetion

    四.self-attention 1.是什么? attention机制通常用在encode与decode之间,但是self-attention则是输入序列与输出序列相同,寻找序列内部元素的关系即 K= ...

  9. js可以随意拖拽的div的实现

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. linux - redis基础

    目录 linux - redis基础 redis 源码编译安装 redis 数据结构 1. strings类型 2. list 类型 3. sets集合类型 有序集合 5. 哈希数据结构 centos ...