试题 3 苏东坡在迁谪黄州期间对竹子情有独钟,他在屋前挂了很多用来当作雨檐的竹子。
某日,天空下起了雨,苏轼静坐在窗前看着窗外,手抚瑶琴,忆古思今。他突然感悟到,人
生之于宇宙,与其说像沧海一栗,不如说更像这眼前的每一个雨滴,虽然飘忽不定,但都有
属于自己的归宿。于是他突发奇想,他想要知道每个落在雨檐上的水滴会落在什么位置,来
印证自己对于人生的拷问。
假设被当作雨檐的竹子的位置都是已知的。如下图所示。可以看出这是一个侧视图。用
线段代表竹子雨檐的位置,图中有三条雨檐P1、 P2、 P3 和两个雨滴Sa、Sb。用水平轴代
表地面。由图可知,Sa下落时落在P3 上,沿P3 滑下并落在P1 上,最终落点为 Ga点。很
明显,雨滴Sb的落点为Gb。给定若干雨檐的位置和若干雨滴的位置,你的任务是让苏轼在
不用淋雨的情况下知道每个雨滴的落点位置。为了简化问题,我们假设没有水平和垂直方向
的雨檐,更没有相互交叉的雨檐。初始状态下所有点(所有雨檐的两个端点处和所有雨滴位
置)在地面的投影互不相同。
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
struct point
{
float x;
float y;
};
struct line
{
point begin;
point end;
};
struct tmiy
{
int i;
float y;
};
void main()
{
float linenum,rainnum;
float px1,py1,px2,py2;
float rainx,rainy;
struct line lne;
vector<line>Ln;
vector<int>visited;
vector<tmiy>temp;
ifstream stream("input.txt");
stream>>linenum;
visited.insert(visited.begin(),linenum,0);
for(int i=1;i<=linenum;i++)
{
stream>>px1>>py1>>px2>>py2;
if(px1>px2)
{
lne.begin.x=px2;
lne.begin.y=py2;
lne.end.x=px1;
lne.end.y=py1;
}
else
{
lne.begin.x=px1;
lne.begin.y=py1;
lne.end.x=px2;
lne.end.y=py2;
}
Ln.push_back(lne);
}
stream>>rainnum;
for(int j=1;j<=rainnum;j++)
{
stream>>rainx>>rainy;
for(int i=1;i<=linenum;i++)
{
for(int k=0;k<Ln.size();k++)
{
int node=rainy-Ln[k].begin.y-(((Ln[k].end.y-Ln[k].begin.y)/(Ln[k].end.x-Ln[k].begin.x))*(rainx-Ln[k].begin.x));
if(visited[k]==0&&node<0&&(rainx>=Ln[k].begin.x)&&(rainx<=Ln[k].end.x)){ visited[k]=1;}
else
{
if(visited[k]==0)
{
if((rainx>=Ln[k].begin.x)&&(rainx<=Ln[k].end.x)&&node>=0)
{
float ry;
struct tmiy t;
ry=Ln[k].begin.y-((Ln[k].end.y-Ln[k].begin.y)/(Ln[k].end.x-Ln[k].begin.x))*(Ln[k].begin.x-rainx);
t.i=k;
t.y=ry;
temp.push_back(t);
}
}
}//else
}//for k
if(temp.size()>0)
{
tmiy tp=temp.front();
for(int m=1;m<temp.size();m++)
{
if(tp.y<temp[m].y)
{
tp.y=temp[m].y;
tp.i=temp[m].i;
}
}
int a=tp.i;
visited[a]=1;
if(Ln[a].begin.y>Ln[a].end.y)
{
rainx=Ln[a].end.x;
rainy=Ln[a].end.y;
}
else
{
rainx=Ln[a].begin.x;
rainy=Ln[a].begin.y;
}
temp.clear();
}//if temp
else{ break; }
}//for i
cout<<rainx<<endl;
visited.clear();
visited.insert(visited.begin(),linenum,0);
}//for j
}