ZZNU-OJ-2118 -(台球桌面碰来碰去,求总距离)——模拟到爆炸【超时】的不能AC的代码
ZZNU-2118 : 早安晚安,不如我先入土为安
题目描述
spring比较喜欢玩台球,因为看着台球在桌子上碰来碰去很有意思(台球撞壁反弹,入射角等于反射角),每次完美的台球入洞,都能体现他数学天才的能力。机房的大佬们当然不承认spring能力强,而是认为每次都是运气而已。
spring很不服气,但又打不过机房大佬,争执过程中聪明的渣渣宥终于想到了完美的办法,那也就是建立数学模型,交给脸红脖子粗的spring来解决。
题目给出一组(x,y),表示矩形的四个点分别为(0,0)(x,0)(0,y)(x,y),构成一个密闭的矩形,只有一个入口(也是唯一的出口)在原点也就是(0,0),假设一个点在原点按照角度(ay=bx)射入矩形中,所拥有的动能为E,每次接触墙壁并反弹所消耗的动能为W,如果射到除原点以外的三个顶点,将原路返回,并且消耗动能W。忽略摩擦力的影响,求出球在矩阵中运动的位移之和,保留两位有效数字。
输入
输入为六个正整数x,y,a,b,E,W。x,y,a,b均小于2000,E,W属于int
输出
求出球在矩阵中运动的位移之和,保留两位有效数字。
样例输入
1 1 1 1 1 1
1 1 1 1 2 1
样例输出
1.41
2.83
模拟了四个小时,WA了,瞬间原地爆炸了;
第二天接着找bug,调了后台数据看了看发现一些细节问题,做了一天的这道题,完整地复习了好多几何的知识点!!
我把超时的代码放着了,纪念一下下。
思路是对的,针对上限E=2*10^9,模拟——时间显然会超限!23333
放一组后台数据,可能会对你有所帮助——
INPUT
1 3 3 1 17 1
OUTPUT
17.92
超时的代码,大部分数据正确——
思路:
1、每一步严格分类讨论,计算出是否撞到源点(第一次例外),是否撞到其他三个顶点——具体是哪一个顶点,是否撞到四条边——具体是那一条边!然后分别根据具体情况,求出相应碰撞时的坐标和反射角等参数,进入下一次循环!
2、初始时,由一个顶点和一个ay=bx的射线方程可以推出这条射线的方程的K和b ,简单的方法就是把它延伸成一条相当长的线段来处理,只需坐标加上M和K*M即可!
3、代码精简了好几次,发现某些思路写的代码其实可以大大省去!
4、还有其他方法也阔以解决,比如:数学方法,相似比方法。
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<string>
#include<algorithm>
#define ll long long
using namespace std;
#include<math.h>
#define N 1008
#define M 10008
#define dinf 1000000.0
double X,Y,a,b,E,W;
const double eps=1e-;
#define PI 3.14159265358
struct Point
{
double x,y;
Point(double x=0.0,double y=0.0):x(x),y(y) {}
} p[];
typedef Point Vector;
struct line
{
Point e,f;
double k,b;
} L0,L[]; Vector operator-(Point a,Point b)
{
return Vector(a.x-b.x,a.y-b.y);
}
bool operator==(Point a,Point b)
{
return (fabs(a.x-b.x)<eps)&&(fabs(a.y-b.y)<eps);
}
double cross(Vector t,Vector f) //计算两个向量的叉乘 之模
{
return (t.x*f.y-t.y*f.x);
}
double cross1(Point e, Point f, Point g)///向量ef与向量eg的叉积,左边为负值, 锐角为正值
{
return cross(f-e,g-e);
} int factcover( Point e, Point f, Point g, Point h)///判断两个线段是否相交, 如果不包括端点 直接<0 包括端点为<=minn(极小值)
{
if(min(e.x,f.x)<=max(g.x,h.x)&&///要避免某一边的端点值 在另一边的延长线上
max(e.x,f.x)>=min(g.x,h.x)&&
min(e.y,f.y)<=max(g.y,h.y)&&
max(e.y,f.y)>=min(g.y,h.y)&& ///<=也可以;前四行 大大于小, 大大于小, 大大于小, 大大于小
cross1(e,f,g)*cross1(e,f,h)<0&& ///两条边相交 端点判断容易出错 便需要两条边同时进行; ///己方向量加一异点, 此行相交时结果为负值或0
cross1(e,g,h)*cross1(f,g,h)<0) ///如果两者共点 返回值也是1///轮流己方一点指向两个异点, 此行相交时结果为负值或0
return 1; ///0 0 1 1 3 3 4 4 返回0 0 0 9 9 3 3 4 4 返回1
return ; ///0 0 3 3 3 3 4 4 返回1 0 0 3 3 3 3 4 5 返回1
} void init(double x,double y) //四个顶点,四条边,初始点p0
{
p[]=Point(,);
p[]=Point(,y);
p[]=Point(x,y);
p[]=Point(x,); L[].e=p[],L[].f=p[];
L[].k=dinf;
L[].e=p[],L[].f=p[];
L[].k=;
L[].e=p[],L[].f=p[];
L[].k=dinf;
L[].e=p[],L[].f=p[];
L[].k=; } double Length(Vector A) //利用点积求向量长度
{
return sqrt(A.x*A.x+A.y*A.y);
} double DisToLine(Point P,Point A,Point B) //点到直线的距离
{
Vector v1=B-A,v2=P-A;
return fabs(cross(v1,v2))/Length(v1);
}
void factk(line &s) //将线段的边长延伸M倍
{
s.e.x+=1.0*M;
s.e.y+= s.k * M;
s.f.x-=1.0*M;
s.f.y-= s.k * M;
}
void launch(line &s,Point &p0,int begnum, double &ans) //反射,并返回碰撞数据
{
//求触碰边(角落),返回 反射后的射线S的 p0、k、b系数;
int flag=;
//先检查是否撞到了四个点上,再检查是否撞到了四条边上
for(int i=; i<=; i++) ///直接拿延长后的射线同四个顶点进行求最短距离,为0的为碰撞角
{
if(i!=begnum- && DisToLine(p[i],s.e,s.f)<eps)
{
flag=i;break;
}
} if(flag==) //本次弹射将撞到 第flag的边上
{
for(int i=;i<=;i++){ ///先平判断撞到编号为 flAG的 边上
if(i!=begnum&&factcover(s.e,s.f,L[i].e,L[i].f)==){
flag=i;
break;
}
} double newk,newb; // cout<<" 边:"<<flag;
if(flag==||flag==) //两条竖着的边
{
double x=L[flag].e.x;
double y=s.k*x+s.b;
ans+=Length(p0-Point(x,y));
p0=Point(x,y); newk=-*s.k;
newb=y-x*newk;
}
else //两条横着的矩形边
{
double y=L[flag].e.y;
double x=(y-s.b)/s.k;
ans+=Length(p0-Point(x,y));
p0=Point(x,y); newk=-*s.k;
newb=y-x*newk;
} s.k=newk;
s.b=newb;///更新反射后的射线S 的k和b
}
else
{ // cout<<" 角:"<<flag;
ans+=Length(p0-p[flag]);
p0=p[flag]; s.k=s.k;
s.b=s.b;///碰撞到四个角后原路返回,k不变!b不变!
} }
int main()
{ while(scanf("%lf",&X)!=EOF)
{
scanf("%lf%lf%lf%lf%lf",&Y,&a,&b,&E,&W);
init(X,Y);
int Time=; Point p0=Point(,); //初始起点和射线
line s;
s.k=b / a;
s.b=0.0;
double ans=0.0; while(E>)
{
++Time;
// if(Time%100000==0)printf(" Time*1e^5=%d\n",Time);
int begnum=-;
for(int i=; i>=; i--) //四个角编号为1+4--4+4
{
if(p[i]==p0){
begnum=i+;break;
} }
for(int i=; begnum==-&&i<=; i++) //四条边为1--4
{
if(DisToLine(p0,L[i].e,L[i].f)<eps)
{
begnum=i;
}
} // printf("beg=%d p0= %lf,%lf s.k=%lf s.b=%lf total_ans:%lf ",begnum,p0.x,p0.y,s.k,s.b,ans);
if(Time>&&begnum==)break;///从源点冲出去了 s.e=p0;
s.f=p0;//当前射线方程;
factk(s);//由点扩展成线 launch(s,p0,begnum,ans);//发射小球,计算出新的碰撞点存入p0中,并更改a,b
E-=W;//减去动能
}
printf("%.2lf\n",ans);
} return ;
}
(点一下写一天,bug不花一分钱)
ZZNU-OJ-2118 -(台球桌面碰来碰去,求总距离)——模拟到爆炸【超时】的不能AC的代码的更多相关文章
- ZZNU - OJ - 2080 : A+B or A-B【暴力枚举】
2080 : A+B or A-B(点击左侧标题进入zznu原题页面) 时间限制:1 Sec 内存限制:0 MiB提交:8 答案正确:3 提交 状态 讨论区 题目描述 Give you three s ...
- [ACM_模拟] ZJUT OJ 1139 七龙珠 (追及类问题,s-t图像,模拟)
Description 话说孙悟饭与小林正在与刚造访地球的赛亚人贝吉塔交战,因为连贝吉塔的手下纳巴的实力也远在他俩之上,由于差距悬殊,小林不得不设脱离战场,去寻找正在修炼中的悟空求救,而赛亚人一伙 ...
- Just Oj 2017C语言程序设计竞赛高级组A: 求近似值(矩阵快速幂)
A: 求近似值 时间限制: 1 s 内存限制: 128 MB 提交 我的状态 题目描述 求⌊(5–√+6–√)2n⌋⌊(5+6)2n⌋%9932017. 例如:n=1,(5–√+6–√)2( ...
- OI/ACM 刷题网站 人气OJ简介
SPOJ简介 SPOJ是波兰最为出色的Online Judge之一,界面和谐,题目类型也非常丰富,适合有一定基础的选手练习,对高手而言也是个提高能力的良好平台. SPOJ题目分类:class ...
- 台球游戏的核心算法和AI(2)
前言: 最近研究了box2dweb, 觉得自己编写Html5版台球游戏的时机已然成熟. 这也算是圆自己的一个愿望, 一个梦想. 承接该序列的相关博文: • 台球游戏核心算法和AI(1) 同时结合htm ...
- 【Tsinghua OJ】多米诺骨牌(domino)问题
(domino.c/cpp)[问题描述] 小牛牛对多米诺骨牌有很大兴趣,然而她的骨牌比较特别,只有黑色和白色的两种.她觉 得如果存在连续三个骨牌是同一种颜色,那么这个骨牌排列便是不美观的.现在她有n个 ...
- nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞
第0.1节 HTML5和桌面软件开发的碰撞 当我们谈论桌面软件开发技术的时候,你会想到什么?如果不对技术本身进行更为深入的探讨,在我的世界里,有这么多技术概念可以被罗列出来(请原谅我本质上是一个Win ...
- 如何在Windows Server 2008 上添加RD (远程桌面)会话主机配置的远程桌面授权服务器
在Windows Server系列的现存活跃产品中都默认的会开放两个随机附送的远程控制的授权,而一些特殊条件下我们需要启用多个远程终端连接,在购买了相应的授权之后,我们如何将配置好的服务器添加到远程桌 ...
- 【Java】深深跪了,OJ题目Java与C运行效率对比(附带清华北大OJ内存计算的对比)
看了园友的评论之后,我也好奇清橙OJ是怎么计算内存占用的.重新测试的情况附在原文后边. -------------------------------------- 这是切割线 ----------- ...
随机推荐
- 【CUDA开发】CUDA编程接口(一)------一十八般武器
子曰:工欲善其事,必先利其器.我们要把显卡作为通用并行处理器来做并行算法处理,就得知道CUDA给我提供了什么样的接口,就得了解CUDA作为通用高性能计算平台上的一十八般武器.(如果你想自己开发驱动,自 ...
- Flink中案例学习--State与CheckPoint理解
1.State概念理解 在Flink中,按照基本类型,对State做了以下两类的划分:Keyed State, Operator State. Keyed State:和Key有关的状态类型,它只能被 ...
- [转载]Oracle中动态SQL详解
1.静态SQLSQL与动态SQL Oracle编译PL/SQL程序块分为两个种:其一为前期联编(early binding),即SQL语句在程序编译期间就已经确定,大多数的编译情况属于这种类型:另外一 ...
- EMR目录
EMR目录: E-MapReduce 是阿里云上的开源大数据平台,用户可以登录集群主节点查看相关安装路径. 登录后也可以使用 env |grep xxx 查看. 或者,在EMR Hadoop集群,切换 ...
- airflow安装rest api插件发现airflow webserver服务不能启动的解决办法
安装插件airflow-rest-api 1)获取 wget https://github.com/teamclairvoyant/airflow-rest-api-plugin/archive/ma ...
- swagger 爬坑记
Swagger 的好处不用我多说,但是一不小心可能就被坑……今天下午就被上了一课,废话不多说,直接上代码(图) 实体类: 好像没啥问题,对吧? 但是,在http://localhost:8080/sw ...
- IDEA使用 maven 搭建 SSM 框架
文章目录 pom 文件的编写 项目结构 SSM 配置文件的编写 web.xml 的配置 总结 公司有个小的内部使用的软件,让开发,自己选择使用 SSM :因为之前自己学过,本以为一切水到渠成,但是好久 ...
- ndarray笔记
Numpy的介绍 1. Ndarray:N-dimensional array, N维数组 2. 一种由相同类型的元素组成的多维数组,元素数量是事先指定好的 例:建立Ndarray多维数组 nd ...
- Struts2连接Mysql的Crud使用
今天分享的是struts2框架中增删改查的用法: 一:利用Struts2框架 1.1在pom.xml中导入相关依赖 <project xmlns="http://maven.apach ...
- (十七)Activitivi5之组任务分配
一.需求分析 我们在实际业务开发过程中,某一个审批任务节点可以分配一个角色(或者叫做组),然后属于这个角色的任何一个用户都可以去完成这个任务节点的审批 二.案例 2.1 方式一:直接流程图配置中写死 ...