[原创]百度之星2009初赛第二场第四题解答

百度之星2009程序设计大赛 初赛第二场第四题解答


题目:

4. 我的地盘 (350分)

题目描述

百度公司的员工们在工作之余,经常以产品组为单位组织一些活动,包括吃大餐、春游秋游、公益活动、唱KTV、看电影、体育比赛等。这些活动有一个专业的名字,叫做team building,我们也亲切的称之为“bui”。

bui

最近,地图产品组刚刚完成一个大项目,大家决定大bui一场。一阵七嘴八舌后,很多内容被提了出来,最终确定先打乒乓球,然后吃饭,最后K歌。问题是,谁也不知道有什么地方可以同时满足这三个需求。

不过没有什么问题可以难倒我们的工程师。很快,就有人写出了程序,为大家找到了合适的地点。

地图覆盖之处,皆为我的地盘。你想挑战一下我们的工程师吗?想为我们找出更合适的地点吗?那就来吧。

输入格式

第1行是一个整数k,表示某范围内所有的POI(Point of Interest)点数量,后续k行每行用5个字段描述一个POI点。它们的含义和格式如下表:

内容 数据格式 数据范围

POI编号 Int,唯一 [0,231-1]

POI类型 字符串 0-16字节(不超过15种类型)

POI级别 Int 0-5(越大表示越高级)

POI经度 Double [0,180],6位有效精度

POI纬度 Double [0,180],6位有效精度

需要注意的是这里的经纬度跟通常的经纬度范围是不一样的

随后是一个整数n(0 < n <= 20),表示共n组查询。以下n行,每行表示一组查询,格式为:

POI类型1 POI类型2 POI类型3 最低级别 最高级别

分别表示三个bui地点各自的类型、最低级别和最高级别。

输出格式

对于每组查询”t1 t2 t3 min max”,输出三个POI编号p1、p2、p3,满足:

•p1、p2、p3的类型分别为t1、t2和t3。

•p1、p2、p3的级别不小于min,不大于max。

•p1、p2、p3的两两欧几里得距离之和应尽量小。

输入数据保证至少存在一个解。

样例输入

5

1 休闲娱乐 3 11.122843 12.431021

2 餐饮服务 2 13.384021 10.230425

3 旅游景点 3 12.234492 9.234268

4 休闲娱乐 5 20.242391 39.304233

5 教育机构 1 42.243292 67.232065

1

休闲娱乐 餐饮服务 旅游景点 0 5

样例输出

1 2 3

测试数据

点击此处下载一份POI数据。所有测试点中的POI数据都基于此数据生成。可能的变动包括:

•修改POI编号

•对经纬度加入随机干扰(变化不会超过1%)。

•修改POI类别和级别

•加入不超过1%的新点,各项属性均完全随机

共20组测试点,其中第i个测试点包含i组查询。1 <= i <= 20

注意事项

•对于每个测试点,设已知最优解为D,则不超过1.05D的任意解均是可以接受的。

•请不要把离线计算的结果保存在源代码中(例如,直接把某些输入的答案保存在常量数组中,读取输入后直接输出),否则本题得0分。

分析:由于不需要求最优解,因此不用全部遍历,使用贪心法寻找离 当前已选择点集合 最近的点,不过没有测试是否最优,比赛的时候提交的是没有优化的代码,比完后又花了半个钟才完成了以下代码,感觉编码速度还是有待加强。

我的水平只能弄出这样的结果了,不过应该还有更优的解法。

#include <stdio.h>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct POI
{
    int id;
    string kind;
    int level;
    double x;
    double y;
};
int main()
{
    int k,n,i,j;
    vector<POI> all;
    scanf("%d",&k);
    for(i=0;i<k;i++)
    {
        POI temp;
        cin>>temp.id>>temp.kind>>temp.level>>temp.x>>temp.y;
        all.push_back(temp);
    }
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        string t[3];
        int min,max;
        cin>>t[0]>>t[1]>>t[2]>>min>>max;
        int index[3]={0},totalindex[3]={0};
        index[0]=-1;
        double totalmindis = 360*360*3;
        //方法:第一个POI选择所有可能的值,然后对每个可能的第一个POI,选择离他最近的第二个POI,
        //选好第二个后,选择离前面两个距离之和最小的那个为第三个POI,
        //选好三个后计算总距离,如果小于前一个解则更新解,终结条件是找到所有可能的第一个POI

        while(index[0]<(int)all.size())
        {
            double curtotal = 0;
            for(j=0;j<3;j++)
            {
                double mindis1 = 360*360;
                double mindis2 = 360*360*2;
                for(k=0;k<all.size();k++)
                {
                    if(t[j]==all[k].kind&&all[k].level>=min&&all[k].level<=max)
                    {
                        //第一个POI
                        if(j==0)
                        {
                            if(k>index[0])
                            {
                                index[j] = k;
                                break;
                            }
                        }
                        //第二个POI
                        else if(j==1)
                        {
                            double dis = (all[k].x-all[index[j-1]].x)*(all[k].x-all[index[j-1]].x)+
                                (all[k].y-all[index[j-1]].y)*(all[k].y-all[index[j-1]].y);
                            if(dis<mindis1)
                            {
                                index[j]=k;
                                mindis1 = dis;
                            }
                        }
                        //第三个POI
                        else if(j==2)
                        {
                            double dis=0;
                            int t;
                            for(t=0;t<j;t++)
                            {
                                dis += (all[k].x-all[index[t]].x)*(all[k].x-all[index[t]].x)+
                                    (all[k].y-all[index[t]].y)*(all[k].y-all[index[t]].y);
                            }
                            if(dis<mindis2)
                            {
                                index[j]=k;
                                mindis2 = dis;
                            }
                        }
                    }
                }
                //计算当前的总距离
                if(j==1)
                    curtotal += mindis1;
                if(j==2)
                    curtotal += mindis2;
                //判断是否已经试过第一个POI的所有可能
                if(j==0&&k==all.size())
                    index[j]=k;
            }
            if(curtotal<totalmindis&&index[0]!=all.size())
            {
                totalindex[0] = index[0];
                totalindex[1] = index[1];
                totalindex[2] = index[2];
                totalmindis = curtotal;
            }
        }
        cout<<all[totalindex[0]].id<<" "<<all[totalindex[1]].id<<" "<<all[totalindex[2]].id<<endl;
    }
    return 0;
}

弄了一组测试数据:
15
1 休闲娱乐 5 20.242391 39.304233
2 餐饮服务 2 13.384021 10.230425
3 旅游景点 3 12.234492 9.234268
4 休闲娱乐 3 11.122843 12.431021
5 教育机构 1 42.243292 67.232065
6 餐饮服务 2 113.054282 29.098546357
7 旅游景点 5 116.834988 39.952290455
8 旅游景点 5 113.166512 22.922672903
9 餐饮服务 2 113.054439 29.0987291154
10 文化教育 3 113.282175 23.201096485
11 综合商场 5 113.166579 22.923254613
12 金融行业 1 117.219020 36.500982133
13 文化教育 5 113.755876 39.739886517
14 综合商场 3 114.120915 36.1436581215
15 金融行业 5 104.688191 30.1736361401
5
休闲娱乐 餐饮服务 旅游景点 0 5
餐饮服务 休闲娱乐 旅游景点 0 5
金融行业 文化教育 综合商场 0 5
旅游景点 餐饮服务 金融行业 0 5
文化教育 餐饮服务 金融行业 0 5

我的答案是:
4 2 3
2 4 3
12 13 14
7 9 12
13 9 12

转载于:https://www.cnblogs.com/absolute8511/archive/2009/05/31/1649573.html

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值