(全国多校重现赛一)D Dying light


LsF is visiting a local amusement park with his friends, and a mirror room successfully attracts his attention. Inside the mirror room, there are n plane mirrors standing vertically on the ground. They are placed end-to-end and face-to-face so that if you overlook the room, you can find a convex hull and the all the reflector surfaces are inside the pattern. The height of the mirror is not important in this problem. 
Due to imperfect manufacturing techniques, mirrors can't reflect light without lose of energy. Each mirror has a reflection efficiency k, which means if the incident light's intensity is I, the reflected light's intensity will be reduced to kI. The only exception could happen when the light precisely goes to the two mirrors' junction. In that case, the light will be completely absorbed instantly. Note the laws of reflection of light applies in all other situations, that the angle of incidence equals the angle of reflection. 
Now LsF stands inside the mirror hall, and shoots a laser beam paralleled to the ground using his laser pointer. Unfortunately, his laser pointer can only shot laser beams with intensity of 1. What's worse, a laser beam is considered disappeared if its intensity is below 10−410−4. There's not much magnitude distance between the two numbers. 
LsF wants to know how many touches can his laser beam make with mirrors before it disappears. 

Input

The first line contains an integer n(3≤n≤1000), indicating the number of mirrors; 
Then n lines follow. The ith line contains three real numbers xi,yi,ki(−109≤xi,yi≤109;0≤ki≤0.9)xi,yi,ki(−109≤xi,yi≤109;0≤ki≤0.9), which means the ith mirror's one end is at position (xi,yi)(xi,yi) and another end is at (xi+1xi+1mod n,yi+1yi+1mod n), and its reflectivity is kiki. 
Next there are two real numbers Vx,Vy(-109≤Vx,Vy≤109), indicating the initial direction vector of the laser beam. 
LsF is standing at the origin (0, 0). 
 

Output

Output an integer in one line, the number of touches the laser beam could make before it disappears.

Sample Input

4
1 2 0.5
-1 0 0.5
1 -2 0.5
3 0 0.5
0 1
4
1 1 0.5
-1 1 0.5
-1 -1 0.5
1 -1 0.5
1 1

Sample Output

14
1

 

题解:因为0.1<=K<=0.9因此最多反射100,就一定可以消失。首先,我们判断该射线是否可以与镜面相交,如果与某一镜面相交,我们再判断是指向镜面还是反向指向镜面的,然后,我们可以计算出射线,与镜面的交点(用两个向量的投影相等)。然后更新O点与向量V;

#include<bits/stdc++.h>
using namespace std;

struct Point{
	double x,y,k;
} point[2010];
Point V;
Point vec(Point a,Point b)
{
	return Point{a.x-b.x,a.y-b.y};
}

double cha_ji(Point a,Point b) //判断是否相交 
{
	return a.x*b.y-a.y*b.x;
}

Point jiao_point(Point O,Point V,Point a,Point b)//求交点 
{
	double dx=a.x-b.x;
	double dy=a.y-b.y;
	double t= ((O.x-a.x)*dy-(O.y-a.y)*dx)/(V.y*dx-V.x*dy);
	return Point{O.x+t*V.x,O.y+V.y*t};
} 

double Nod(Point a,Point b)
{
	return a.x*b.x+a.y*b.y;
}

int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		for(int i=0;i<n;i++) scanf("%lf%lf%lf",&point[i].x,&point[i].y,&point[i].k);
		Point O{0,0};
		scanf("%lf%lf",&V.x,&V.y);
		double power=1;
		int ans=0,flag=0;
		while(power>=1e-4)
		{
			for(int i=0;i<n;i++)
			{
				if(cha_ji(V,vec(point[i],O))*cha_ji(V,vec(point[(i+1)%n],O))<0)
				{
					Point nod=jiao_point(O,V,point[i],point[(i+1)%n]);
					if(Nod(V,vec(nod,O))<0) continue;
					double dx=point[(i+1)%n].x-point[i].x;
                	double dy=point[(i+1)%n].y-point[i].y;
                	Point nex=(Point) {O.x-2*dx*(dx*O.x+dy*O.y-nod.x*dx-nod.y*dy)/(dx*dx+dy*dy),O.y-2*dy*(dx*O.x+dy*O.y-nod.x*dx-nod.y*dy)/(dx*dx+dy*dy)};
                	V=vec(nex,nod);
                	O=(Point){nod.x+0.1*V.x,nod.y+0.1*V.y};                                                                                         
               		ans++;
                	power*=point[i].k;
					break;
				}
				else if(cha_ji(V,vec(point[i],O))*cha_ji(V,vec(point[(i+1)%n],O))==0) 
				{
					ans++;flag=1;
					break;
				}
			}
			if(flag) break;
		}
		cout<<ans<<endl;
	}
	return 0;
}

 

posted @ 2018-07-25 17:25  StarHai  阅读(205)  评论(0编辑  收藏  举报