uva10012 不是那么简单的,有陷阱!

这道题第一次做以为是一般的回溯题,最初的思路就是将各圆形全排列,放置新圆的时候让其与前一个圆相切,最后通过回溯得到矩形的最小size。十几分钟编完后结果WA,想了好一会发现问题所在,不能只让其与前一个圆相切(如果第一个圆很大,半径比方说是100,第二个圆很小,半径是1,第三个圆也很大,半径同样是100,放第三个圆的时候如果是和第二个圆相切则必定会与第一个圆相交,就不可以了)。然后就开始修改代码,然后就遇到了各种错误,断断续续地弄了一晚上加一上午。
 
首先想的是每次放一个圆形的时候还是先让其与前一个放置的圆相切,然后判断它与再之前放的圆是否相交,如不相交,则说明这样放是正确且最节省距离的,如果有任何一个圆与其相交,则说明不能与前一个圆相切,就再往前推一个,让其与前前个圆相切,再判断是否和别的圆相交。。。为了判断是否相交,增加了一个center数组存储各圆的圆心位置。到此思路很正确很清晰,然后遇到了三个Wa的点。
 
WA1:判断矩形最小size的时候不能用最后一个圆的最右侧位置了,因为有可能最后一个圆很小,其最右侧的位置还不如其前一个圆的最右侧位置远,所以改用判断各圆圆心位置+半径的最大值作为矩形的最小size。
 
WA2:在放置前几个圆的时候注意不能让圆的圆心位置-圆的半径<0。比如说第一个圆半径是1,第二个元半径100,放第二个元就不能让其与第一个圆相切因为那样圆的左边就超出矩形盒子的壁了!
 
WA3:主函数中MinL设置的太小,估计测试数据的数有很大的,题目没有说半径最大是多少,开始设的是65536,结果WA,改成DBL_MAX就AC了!!
 
 

#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<float.h>
using namespace std;  

int m,Put[10];          //Put[i]:放置的第i个圆的编号
double MinL,size[10],center[10];//size[i]:编号为i的圆的半径;center[i]:放置的第i个圆的圆心位置
bool vis[10];  

double getlen(int a,int b)      //计算两圆心间的距离
{
    return sqrt((size[a]+size[b])*(size[a]+size[b])-(size[a]-size[b])*(size[a]-size[b]));
}
bool isok(int a,int b)          //是否和之前放的圆相交
{
    for (int i=0;i<b;i++)
    {
        if (sqrt((center[i]-center[a])*(center[i]-center[a])+(size[Put[i]]-size[Put[a]])*(size[Put[i]]-size[Put[a]]))<(size[Put[i]]+size[Put[a]]))
            return false;
    }
    return true;
}
void dfs(int cur)
{
    int i,j;
    if (cur==m)
    {
        double maxsize=0;
        for (int k=0;k<cur;k++)
        {
            if (center[k]+size[Put[k]]>maxsize)
                maxsize=center[k]+size[Put[k]];
        }
        if (maxsize<MinL)
            MinL=maxsize;
    }
    else
    {
        for (i=0;i<m;i++)
        {
            if (!vis[i])
            {
                Put[cur]=i;
                vis[i]=1;
                double tmpl;
                bool ok=1;
                for (j=cur-1;j>=0;j--)
                {
                    tmpl=getlen(Put[j],i);
                    center[cur]=center[j]+tmpl;
                    if (center[cur]-size[Put[cur]]<0)
                    {ok=0;break;}
                    if (isok(cur,j)) break;
                }
                if (ok)
                    dfs(cur+1);
                vis[i]=0;
            }
        }
    }
}
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        cin>>m;
        MinL=DBL_MAX;
        memset(vis,0,sizeof(vis));
        for (int i=0;i<m;i++)
            cin>>size[i];
        for (int i=0;i<m;i++)
        {
            Put[0]=i;
            center[0]=size[i];
            vis[i]=1;
            dfs(1);
            vis[i]=0;
        }
        cout<<fixed<<setprecision(3)<<MinL<<endl;
    }
    return 0;
}

 

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索位置
, 矩形
, 一个
, 矩形相交
, 右侧
, 相交
, 最小
, 判断位置
, 陷阱题
画不相交的圆
5个简单的捕鸟陷阱、最简单的自动捕鸟陷阱、我的世界简单杀怪陷阱、我的世界简单陷阱大全、做简单机关和陷阱,以便于您获取更多的相关知识。

时间: 2024-07-30 13:25:57

uva10012 不是那么简单的,有陷阱!的相关文章

给黑客设一个“死亡陷阱”

       一个成功的防护措施,可以拖延攻击者,同时能给防御者提供足够的信息来了解黑客,将攻击造成的损失降至最低.网络安全防御者通过提供虚假信息,迫使攻击者浪费时间做无益的进攻,以减弱后续的入侵力量; 同时,还可获得攻击者手法和动机等相关信息,这些信息日后可用来强化现有的安全措施,例如防火墙规则和配置等.网络陷阱技术就是基于这一思路设计和开发的.     设置陷阱 网络陷阱技术主要包括: 伪装技术(系统伪装.服务伪装等).诱骗技术.引入技术.信息控制技术(防止攻击者通过陷阱实现跳转攻击).数据

ZooKeeper编程指导

原文链接  译者:zivyu 简介 对于想要利用ZooKeeper的协调服务来创建一个分布式应用的开发人员来说,这篇文章提供了指导.包含了一些概念和实际性操作的信息. 这篇文章的前四个章节介绍了各种ZooKeeper的概念,这对理解ZooKeeper是怎么工作的是必须的.没有包含源代码,但是它假设你对分布式处理有关的问题比较熟悉.这四个章节是: ZooKeeper数据模型 ZooKeeper 会话 ZooKeeper Watches 一致性保证 随后的四个章节提供了实际的编程信息,他们是: 构建

如何充分利用服务器负载平衡器?

对于现代企业应用程序来说,服务器负载平衡是一项非常重要的计算机资源. 无论应用程序是在云中还是本地数据中心中,负载平衡均可以通过像服务器.网段和存储器这样的计算机设备对网络流量进行指引和优化.负载平衡可以提升应用程序性能.优化资源适用以及水平扩展应用程序同时又保持其原有弹性. 不论是软件还是硬件负载平衡器,其最主要的目的就是,根据调度或者其他算法,接收传入的流量请求,并将其均衡或者非均衡的分布到服务器集群中.例如,服务器负载平衡通过计算机集群的四个任务关键型应用程序实例来分布流量.当计算机集群的

找到并留住最佳员工

本文节选自电子书<Netkiller Management 手札> 出处:http://www.netkiller.cn 作者:netkiller , QQ:13721218, 订阅号:netkiller-ebook 2.2.2. 找到并留住最佳员工 每个月我都会接到许多猎头的电话,有些猎头比较专业,但绝大多数在我看来与猎头二字还是有很大差距的. 与猎头接触多了,自然也了解了他们的工作,包括操作手法,总体上国内的猎头行业还处在初级阶段. 总结就是"盲目推荐,以量取胜". 2

7. 招聘与配置

7.1. 面试流程 简历筛选 -> 电话面试 -> 面试(face to face) -> 确定录用 注意:没有笔试这项,没有必要,可以放在面谈中,作为互动的一部分. 不要盲目给应聘者打电话通知他过来面试,HR部门首先应对简历做初步筛选,然后把简历email给技术部门负责人. 技术这边对简历进行审核,然后通知HR部门确认电话面试时间,并了解对方基本情况. 配合HR部门做好电话面试,了解应聘者的技术水平,能力,是否可是胜任该职位.如果OK通知面谈时间,地点,并发一封正式Email邀请函.

SNMP(Simple Network Management Protocol)简单网络管理协议

SNMP(Simple Network Management Protocol)即简单网络管理协议,它为网络管理系统提供了底层网络管理的框架.SNMP协议的应用范围非常广泛,诸多种类的网络设备.软件和系统中 都有所采用,主要是因为SNMP协议有如下几个特点: 首先,相对于其它种类的网络管理体系或管理协议而言,SNMP易于实现.SNMP的管理 协议.MIB及其它相关的体系框架能够在各种不同类型的设备上运行,包括低档的个人电脑到高档的大型主机.服务器.及路由器.交换器等网络设备.一个 SNMP管理代

Web体验的设计师:响应式网页设计的陷阱

文章简介:虽然响应式Web设计仍处于发展初期,但已经有很多指导和最佳实践,当你创建可跨设备工作的设计时可以采用.对于那些希望为使用不同设备的用户提供顶尖Web体验的设计师来说,则需要更多的思考与努力. 设计师们无法回避移动设备的大势所趋,当然在网站设计上有大量新的概念来迎合移动设备.但是单独的网站,无法在移动设备层出不穷的大潮中站稳脚跟.无论是在个人电脑.笔记本.智能手机.平板电脑.大屏幕手机.智能电视.上网本以及其它有前景的设备,都需引人入胜的设计. 响应式布局是这种情况下唯一理智的方式. 尽

JavaScript——以简单的方式理解闭包

      闭包,在一开始接触JavaScript的时候就听说过.首先明确一点,它理解起来确实不复杂,而且它也非常好用.那我们去理解闭包之前,要有什么基础 呢?我个人认为最重要的便是作用域(lexical scope),如果对作用域和作用域链不理解的同学最好自己先去学一学,再回过头来,理解闭包,就更加轻松. 下面便直接进入主题. 我们知道一个函数是有作用域的,在函数内部定义的局部变量只有在函数内部才可以访问的到.一旦函数访问结束被销毁,局部变量随之也会销毁,无法 通过任何方式再次访问局部变量,除

Javascript教程:Javascript中的陷阱

文章简介:Javascript中的陷阱大集合. 本文主要介绍怪异的Javascript,毋庸置疑,它绝对有怪异的一面.当软件开发者开始使用世界上使用最广泛的语言编写代码时,他们会在这个过程中发现很多有趣的"特性".即便是老练的Javascript开发者也可以在本文找到一些有趣的新陷阱,请留意这些陷阱,当然也可以尽情享受由这些陷阱带来的"乐趣"! 函数和操作符 双等号 ==操作符比较时会进行类型的强制转换,这意味着它可以比较两个不同类型的对象,在执行比较之前它将会尝试