110. Dungeon

time limit per test: 0.25 sec. 
memory limit per test: 4096 KB

The mission of space explorers found on planet M the vast dungeon. One of the dungeon halls is fill with the bright spheres. The explorers find out that the light rays reflect from the surface of the spheres according the ordinary law (the incidence angle is equal to the reflectance angle, the incidence ray, the reflected ray and the perpendicular to the sphere surface lay in the one plane). The ancient legend says that if the light ray will reflect from the spheres in the proper order, than the door to the room with very precious ancient knowledge will open. You are not to guess the right sequence; your task is much simpler. You are given the positions and the radii of the spheres, the place where the laser shot was made and the direction of light propagation. And you must find out the sequence in which the light will be reflected from the spheres.

Input

The first line of input contains the single integer n (1≤n≤50) - the amount of the spheres. The next n lines contain the coordinates and the radii of the spheres xi, yi, zi, ri (the integer numbers less or equal to 10000 by absolute value). The last line contains 6 real numbers - the coordinates of two points. The first one gives the coordinates of the place of laser shot, and the second gives the direction in which it was made (the second point is the point on the ray). The starting point of the ray lies strictly outside of any sphere.

Output

Your program must output the sequence of sphere numbers (spheres are numbers from 1 as they was given in input), from which the light ray was reflected. If the ray will reflect more the 10 times, than you must output first 10, then a space and the word 'etc.' (without quotes). Notice: if the light ray goes at a tangent to the sphere you must assume that the ray was reflected by the sphere.

Sample Input 1

1
0 0 2 1
0 0 0 0 0 1

Sample Output 1

1

Sample Input 2

2
0 0 2 1
0 0 -2 1
0 0 0 0 0 100

Sample Output 2

1 2 1 2 1 2 1 2 1 2 etc.

感想:计算几何远观的时候最难
思路:
1 判断射线反射交哪个球 如果使用点斜式会在0处出问题,题解使用了起点到球的距离相对射线反向的倍数,注意当这个倍数为0的时候,只要不是从这个球反射出去的也成立(也就是开始的时候光源就在这个球表面)
2 求反射后的光线向量,做一个以入射光线为平行边的一边,法线(圆心-入射点方向)为对角线做一个菱形,明显反射光线就是另外一边..的反向(!),所以反射光线就是入射向量-入射光线在法线上的投影*2,在这个地方弄成法线在入射光线WA一次
投影为单位法线*(入射和法线的点积)
最后注意一下,先判断有没有第11次反射再输出"etc."
#include<cstdio>
#include <cstring>
#include <cmath>
using namespace std;
class pnt{
public :
double x,y,z;
pnt():x(0),y(0),z(0){}
pnt(double tx,double ty,double tz):x(tx),y(ty),z(tz){}
pnt operator -(pnt besub){
pnt ans;
ans.x=x-besub.x;
ans.y=y-besub.y;
ans.z=z-besub.z;
return ans;
}
pnt operator +(pnt beadd){
pnt ans;
ans.x=x+beadd.x;
ans.y=y+beadd.y;
ans.z=z+beadd.z;
return ans;
}
pnt operator*(double bemul){
pnt ans;
ans.x=x*bemul;
ans.y=y*bemul;
ans.z=z*bemul;
return ans;
}
pnt operator/(double bediv){
pnt ans;
ans.x=x/bediv;
ans.y=y/bediv;
ans.z=z/bediv;
return ans;
}
double dot(pnt bepnt){
return x*bepnt.x+y*bepnt.y+z*bepnt.z;
}
double caldis(pnt other){
return sqrt((x-other.x)*(x-other.x)+(y-other.y)*(y-other.y)+(z-other.z)*(z-other.z));
}
double len(){
return sqrt(x*x+y*y+z*z);
}
}; pnt ball[51],nowref,dir,start,normal;
double ballr[51],mindis,nowdis;
int n,nowball,nxtball;
const double inf=1e18;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lf%lf%lf%lf",&ball[i].x,&ball[i].y,&ball[i].z,ballr+i);
}
scanf("%lf%lf%lf%lf%lf%lf",&start.x,&start.y,&start.z,&dir.x,&dir.y,&dir.z);
dir=dir-start;
dir=dir/dir.len();
nowball=0;
for(int time=0;time<11;time++){
nxtball=0;
mindis=inf;
for(int i=1;i<=n;i++){//开始使用了点法式,不行...换成比例简洁不出错
if(i==nowball)continue;
double a=dir.x*dir.x+dir.y*dir.y+dir.z*dir.z;
double b=2*(dir.x*(start.x-ball[i].x)+dir.y*(start.y-ball[i].y)+dir.z*(start.z-ball[i].z));
double c=(start.x-ball[i].x)*(start.x-ball[i].x)+(start.y-ball[i].y)*(start.y-ball[i].y)+(start.z-ball[i].z)*(start.z-ball[i].z)-ballr[i]*ballr[i];
double delta=b*b-4*a*c;
if(delta<0)continue; nowdis=(-b+sqrt(delta))/2/a;
if(nowdis>=0&&nowdis<mindis){//ATTENTION
mindis=nowdis;
nxtball=i;
nowref=start+dir*(nowdis);
}
nowdis=(-b-sqrt(delta))/2/a;
if(nowdis>=0&&nowdis<mindis){//ATTENTION
mindis=nowdis;
nxtball=i;
nowref=start+dir*(nowdis);
}
} if(nxtball==0){break;}
if(time)putchar(' ');
if(time<10)printf("%d",nxtball);
else {puts("etc.");break;} normal=ball[nxtball]-nowref;
normal=normal/normal.len();
dir=dir-normal*(normal.dot(dir)*2.00);
start=nowref;
nowball=nxtball;
}
return 0;
}

  

SGU 110. Dungeon 计算几何 难度:3的更多相关文章

  1. sgu 110 Dungeon

    这道题是计算几何,这是写的第一道计算几何,主要是难在如何求入射光线的反射光线. 我们可以用入射光线 - 入射光线在法线(交点到圆心的向量)上的投影*2 来计算反射光线,自己画一个图,非常清晰明了. 具 ...

  2. sgu 129 Inheritance 凸包,线段交点,计算几何 难度:2

    129. Inheritance time limit per test: 0.25 sec. memory limit per test: 4096 KB The old King decided ...

  3. SGU 124. Broken line 射线法 eps的精准运用,计算几何 难度:3

    124. Broken line time limit per test: 0.25 sec. memory limit per test: 4096 KB There is a closed bro ...

  4. sgu 125 Shtirlits dfs 难度:0

    125. Shtirlits time limit per test: 0.25 sec. memory limit per test: 4096 KB There is a checkered fi ...

  5. hdu 3694 10 福州 现场 E - Fermat Point in Quadrangle 费马点 计算几何 难度:1

    In geometry the Fermat point of a triangle, also called Torricelli point, is a point such that the t ...

  6. hdu 3685 10 杭州 现场 F - Rotational Painting 重心 计算几何 难度:1

    F - Rotational Painting Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & % ...

  7. poj 3348 Cows 凸包 求多边形面积 计算几何 难度:0 Source:CCC207

    Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7038   Accepted: 3242 Description ...

  8. SGU 分类

    http://acm.sgu.ru/problemset.php?contest=0&volume=1 101 Domino 欧拉路 102 Coprime 枚举/数学方法 103 Traff ...

  9. 2018.10.15 bzoj4445: [Scoi2015]小凸想跑步(半平面交)

    传送门 话说去年的省选计算几何难度跟前几年比起来根本不能做啊(虽然去年考的时候并没有学过计算几何) 这题就是推个式子然后上半平面交就做完了. 什么? 怎么推式子? 先把题目的概率转换成求出可行区域. ...

随机推荐

  1. Python3基础 while 阶乘

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  2. 三点估算和PERT技术

    三点估算是PMP考试中的必考题目,每次约2-4道题目.现在就三点估算和PERT技术做详细讲解,以飨读者. 通过考虑估算中的不确定性和风险,可以提高活动持续时间估算的准确性.这个概念起源于计划评审技术( ...

  3. 【Tomcat部署】Linux环境部署war包到tomcat

    以turbine为例. 一.部署 1.下载或者生成war包(从maven上下载war包,并改名字为turbine.war) 2.将turbine.war拷贝到$TOMCAT_HOME/webapps中 ...

  4. 【Coursera】SecondWeek(1)

    全球互联网的始祖 APRANET APRANET 是 DARPA(美国国防部高级研究计划局) 开发的世界上第一个运营PacketSwitching(分包交换)的网络. 鉴于二战后世界格局两极化的历史背 ...

  5. python-ConfigParser模块--转载

    1,函数介绍 1.1.读取配置文件 -read(filename) 直接读取ini文件内容-sections() 得到所有的section,并以列表的形式返回-options(section) 得到该 ...

  6. django用包来组织模型

    在我们使用python manage.py startapp xxx命令创建新的应用时,Django会自动帮我们建立一个应用的基本文件组织结构,其中就包括一个models.py文件.通常,我们把当前应 ...

  7. hihoCoder 1513 小Hi的烦恼

    hihoCoder 1513 小Hi的烦恼 思路: 用bitset判断交集个数 代码: #include<bits/stdc++.h> using namespace std; #defi ...

  8. onLoad和DomContentLoad的区别

    onLoad是的在页面所有文件加载完成后执行 DomContentLoad是Dom加载完成后执行,不必等待样式脚本和图片加载 domContentLoad更为合理, 原理: 如果是webkit引擎则轮 ...

  9. 对微服务API服务网关的理解

    目录微服务专栏地址目录1. 简介2. 什么是API网关3. 为什么需要API网关4. API网关在微服务架构体系中处于什么位置4.1 调用者眼中的API网关4.2 所处的位置5. 网关技术实现有哪些6 ...

  10. Java注解 框架开发之Java注解的妙用

    原文出处: locality 注解的好处: 1.能够读懂别人写的代码,特别是框架相关的代码. 2.本来可能需要很多配置文件,需要很多逻辑才能实现的内容,就可以使用一个或者多个注解来替代,这样就使得编程 ...