POJ 1269 Intersecting Lines
题意很简单、判断两条直线是重合平行还是相交、如果相交输出交点、
Code:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define EPS 1e-9
#define INF 1e10
using namespace std;
int vv;
double x1,x2,x3,x4,yy1,y2,y3,y4;
bool eq(double x1,double x2){
return abs(x1-x2)<EPS;
}
double slope(double x1,double y1,double x2,double y2){
if (eq(x1,x2)) return INF;
return (y2-y1)/(x2-x1);
}
int main(){
printf("INTERSECTING LINES OUTPUT\n");
scanf("%d",&vv);
while (vv--){
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&yy1,&x2,&y2,&x3,&y3,&x4,&y4);
double k1=slope(x1,yy1,x2,y2),k2=slope(x3,y3,x4,y4);
if (eq(k1,k2))
if ((eq(x1,x2) && eq(x1,x3)) || (eq(yy1-k1*x1,y3-k2*x3)))
printf("LINE\n");
else printf("NONE\n");
else{
double b1=yy1-x1*k1,b2=y3-k2*x3;
printf("POINT %.2lf %.2lf\n",(b2-b1)/(k1-k2),k1*(b2-b1)/(k1-k2)+b1);
}
}
printf("END OF OUTPUT\n");
return 0;
}
POJ 1410 Intersection
判断一条直线和一个矩形是否有公共部分(包含也算)、
Code:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define EPS 1e-9
#define INF 1e10
using namespace std;
struct segment{
double beginx,beginy,endx,endy;
};
double crossp(double x1,double y1,double x2,double y2){
return x1*y2-x2*y1;
}
int cross(segment a,segment b){
if (min(a.beginx,a.endx)>max(b.beginx,b.endx) ||\
min(b.beginx,b.endx)>max(a.beginx,a.endx) ||\
min(a.beginy,a.endy)>max(b.beginy,b.endy) ||\
min(b.beginy,b.endy)>max(a.beginy,a.endy)) return 0;
if (crossp(a.beginx-b.beginx,a.beginy-b.beginy,b.endx-b.beginx,b.endy-b.beginy)\
*crossp(b.endx-b.beginx,b.endy-b.beginy,a.endx-b.beginx,a.endy-b.beginy)>=0 &&\
crossp(b.beginx-a.beginx,b.beginy-a.beginy,a.endx-a.beginx,a.endy-a.beginy)\
*crossp(a.endx-a.beginx,a.endy-a.beginy,b.endx-a.beginx,b.endy-a.beginy)>=00) return 1;
return 0;
}
int vv;
segment temp,p;
double lx,rx,ty,by;
int main(){
scanf("%d",&vv);
while (vv--){
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&temp.beginx,&temp.beginy,&temp.endx,&temp.endy,&lx,&ty,&rx,&by);
if (lx>rx) swap(lx,rx);
if (by>ty) swap(by,ty);
if (temp.beginx>=lx && temp.beginx<=rx && temp.beginy>=by && temp.beginy<=ty &&\
temp.endx>=lx && temp.endx<=rx && temp.endy>=by && temp.endy<=ty){
cout <<'T' <<endl;
continue;
}
p.beginx=p.endx=lx;p.beginy=by;p.endy=ty;
if (cross(temp,p)){
cout <<'T' <<endl;
continue;
}
p.beginx=p.endx=rx;
if (cross(temp,p)){
cout <<'T' <<endl;
continue;
}
p.beginx=lx;p.endx=rx;p.beginy=p.endy=by;
if (cross(temp,p)){
cout <<'T' <<endl;
continue;
}
p.beginy=p.endy=ty;
if (cross(temp,p)){
cout <<'T' <<endl;
continue;
}
else cout <<'F' <<endl;
}
return 0;
}
POJ 1696 Space Ant
卷包裹的概念题、
Code:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define INF 1e9
using namespace std;
struct point{
int x,y;
};
inline int distsquare(point A,point B){return (B.x-A.x)*(B.x-A.x)+(B.y-A.y)*(B.y-A.y);}
inline int det(int x1,int y1,int x2,int y2){return x1*y2-x2*y1;}
inline int cross(point A,point B,point C,point D){return det(B.x-A.x , B.y-A.y , D.x-C.x , D.y-C.y);}
int vv,n;
int main(){
scanf("%d",&vv);
while(vv--){
scanf("%d",&n);
point* node=new point[n+1];
int* conbag=new int[n+1];
bool* vist=new bool[n+1];
int min_y=INF,fi=0;
for(int i=1;i<=n;i++){
int num;
cin>>num>>node[i].x>>node[i].y;
vist[i]=false;
if(min_y > node[i].y){
min_y = node[i].y;
fi=i;
}
}
conbag[1]=fi;conbag[0]=1;vist[fi]=true;
int pc=1;
while(1){
int s=conbag[pc];
int k;
for(int i=1;i<=n;i++)
if(!vist[i]){
k=i;
break;
}
for(int i=1;i<=n;i++)
if(i!=k && !vist[i]){
int temp=cross(node[s],node[k],node[s],node[i]);
if(temp<0) k=i;
else
if(temp==0)
if(distsquare(node[s],node[k]) > distsquare(node[s],node[i])) k=i;
}
conbag[++pc]=k;conbag[0]++;vist[k]=true;
if(n-conbag[0]==1) break;
}
printf("%d ",conbag[0]+1);
fi=0;
for(int i=1;i<=conbag[0];i++){
printf("%d ",conbag[i]);
if(!vist[i]) fi=i;
}
if (fi) cout<<fi<<endl;
else cout<<n<<endl;
delete node;delete conbag;delete vist;
}
return 0;
}
POJ 3347 Kadj Squares
这个题目很有意思、、
首先,因为无论怎么扩大或者缩小边长,只要是同时对所有图形处理,都不会有问题、于是小数问题被解决了、
其次、对于每个正方形,如果它比前面一个小,显然放在那个的“下面”,否则,情况就比较复杂、于是我为乐简化讨论、对前面所有正方形求一下它能摆的最左位置,然后找出其中的最大值、
最后刷一个高度数组来判断可见、
Code:
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define sign printf("*\n")
using namespace std;
int h[5001],v[5001],len[5001],p[5001],fr[5001];
int n;
int main(){
scanf("%d",&n);
while (n){
memset(fr,0,sizeof fr);
for (int i=1;i<=n;i++){
scanf("%d",&len[i]);
len[i]*=4;
}
p[1]=0;
for (int i=2;i<=n;i++)
if (len[i]<len[i-1]) p[i]=p[i-1]+len[i-1]+len[i];
else{
int cur=0;
for (int j=1;j<i;j++)
if (len[j]>len[i]) cur=max(cur,p[j]+len[j]+len[i]);
else cur=max(cur,p[j]+len[j]*3-len[i]);
p[i]=cur;
}
//sign;
memset(h,0,sizeof h);
for (int i=1;i<=n;i++){
int cur=len[i];
for (int j=0;j<len[i];j++){
if (cur>h[p[i]+j]){
h[p[i]+j]=cur;
fr[p[i]+j]=i;
}
cur++;
}
if (cur>h[p[i]+len[i]]){
h[p[i]+len[i]]=cur;
fr[p[i]+len[i]]=i;
}
for (int j=len[i]+1;j<=len[i]*2;j++){
cur--;
if (cur>h[p[i]+j]){
h[p[i]+j]=cur;
fr[p[i]+j]=i;
}
}
}
//for (int i=1;i<=n;i++) printf("%d %d\n",i,p[i]);
memset(v,0,sizeof v);
for (int i=0;i<=5000;i++)
v[fr[i]]++;
int c=0;
for (int i=1;i<=n;i++)
if (v[i]){
if (!c) c++;else printf(" ");
printf("%d",i);
}
printf("\n");
scanf("%d",&n);
}
}
POJ 2826 An Easy Problem?!
太恶心了!、
题意很好理解,然后有以下几种特殊情况:
有水平线;
开口不是朝上的;
两条线段没有交点;
两条线段重合、
以上判断方法都不难、都考虑到就可以了、
(本题实际上是不卡精度的、列方程求解也可过、
Code:
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define EPS 1e-20
#define sqr(x) ((x)*(x))
#define INF 1e9
#define sign printf("*\n")
using namespace std;
struct segment{
double sx,sy,ex,ey;
};
segment s1,s2;
int eq(double xx,double yy){
return abs(xx-yy)<EPS;
}
double dis(double x1,double y1,double x2,double y2){
return sqrt(sqr(x1-x2)+sqr(y1-y2));
}
double crossp(double x1,double y1,double x2,double y2){
return x1*y2-x2*y1;
}
double slope(double x1,double y1,double x2,double y2){
return (eq(x1,x2)?INF:(y2-y1)/(x2-x1));
}
int cross(segment a,segment b){
if (max(a.sx,a.ex)<min(b.sx,b.ex) || max(a.sy,a.ey)<min(b.sy,b.ey) \
|| min(a.sx,a.ex)>max(b.sx,b.ex) || min(a.sy,a.ey)>max(b.sy,b.ey)) return 0;
if (crossp(a.sx-b.sx,a.sy-b.sy,b.ex-b.sx,b.ey-b.sy)*crossp(b.ex-b.sx,b.ey-b.sy,a.ex-b.sx,a.ey-b.sy)>=0 && \
crossp(b.sx-a.sx,b.sy-a.sy,a.ex-a.sx,a.ey-a.sy)*crossp(a.ex-a.sx,a.ey-a.sy,b.ex-a.sx,b.ey-a.sy)>=0) return 1;
else return 0;
}
int main(){
int vv;
scanf("%d",&vv);
while (vv--){
scanf("%lf%lf%lf%lf",&s1.sx,&s1.sy,&s1.ex,&s1.ey);
scanf("%lf%lf%lf%lf",&s2.sx,&s2.sy,&s2.ex,&s2.ey);
if (s1.sy>s1.ey){
swap(s1.sx,s1.ex);
swap(s1.sy,s1.ey);
}
if (s2.sy>s2.ey){
swap(s2.sx,s2.ex);
swap(s2.sy,s2.ey);
}
if (!cross(s1,s2)){
printf("0.00\n");
continue;
}
if (eq(s1.sy,s1.ey) || eq(s2.sy,s2.ey)){
printf("0.00\n");
continue;
}
double k1=slope(s1.sx,s1.sy,s1.ex,s1.ey);
double k2=slope(s2.sx,s2.sy,s2.ex,s2.ey);
if (eq(k1,k2)){
printf("0.00\n");
continue;
}
double b1=s1.sy-k1*s1.sx;
double b2=s2.sy-k2*s2.sx;
double meetx=(b2-b1)/(k1-k2);
double meety=meetx*k1+b1;
double h=min(s1.ey,s2.ey);
double d=abs((h-b1)/k1-(h-b2)/k2);
//printf("%.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf %.2lf\n",k1,b1,k2,b2,meetx,meety,h,d);
if (k1*k2>0)
if (abs(k1)>abs(k2)){
if (abs(s1.ex-meetx)>=abs(s2.ex-meetx)){
printf("0.00\n");
continue;
}
}
else
if (abs(s1.ex-meetx)<=abs(s2.ex-meetx)){
printf("0.00\n");
continue;
}
printf("%.2lf\n",0.5*d*(h-meety)+EPS);
}
}