AC is lucky , WA is life.
問題蟲洞——A: A - TOYS
問題蟲洞——B: B - Toy Storage
兩題個大致思想相同,參考我的另一篇博客吧!:TOYS POJ - 2318 (二分+斜率)
問題蟲洞——C: C - Segments
黑洞內窺:
t組樣例,每組樣例給出n條線段的兩個端點座標
問是否存在這樣一條直線,所以線段在該線段上的投影有公共點。
思維光年:
問題可以轉換爲:是否存在一條直線,使得該直線與所有的線段相交。
然後你枚舉所有線段的端點連線,判斷是否與所有線段相交即可:
ACcode:
//#include<bits/stdc++.h>
#include <stdio.h>
#include <iostream>
#include<algorithm>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <cstring>
#include <string.h>
#include <string>
#include <math.h>
#include <sstream>
using namespace std;
typedef long long int ll;
const ll MAXN = 1005;
#define INF 0x3f3f3f3f//將近ll類型最大數的一半,而且乘2不會爆ll
const ll mod = 100000007;
const double eps = 0.00000001;
struct node
{
double x1, y1, x2, y2;
} stu[MAXN];
int n, t;
double go(double x1, double y1, double x2, double y2)
{
return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
}
double cha(double x1,double y1,double x2,double y2,double x,double y)
{
return (x2-x1)*(y-y1)-(x-x1)*(y2-y1);
}
int so(double x1, double y1, double x2, double y2)
{
if(go(x1, y1, x2, y2) < eps) return 0;//可能點重合
for(int i=0; i<n; ++i)
{
if(cha(x1, y1, x2, y2, stu[i].x1, stu[i].y1) * cha(x1, y1, x2, y2, stu[i].x2, stu[i].y2)>eps)
return 0;
}
return 1;
}
int main()
{
cin >> t;
while(t--)
{
scanf("%d", &n);
for(int i=0; i<n; ++i)
scanf("%lf %lf %lf %lf", &stu[i].x1, &stu[i].y1, &stu[i].x2, &stu[i].y2);
if(n == 1) {
puts("Yes!");
continue;
}
int flag = 0;
for(int i=0; i<n && !flag; ++i)
{
for(int j= i+1; j<n && !flag; ++j)
if(so(stu[i].x1, stu[i].y1, stu[j].x1, stu[j].y1) || so(stu[i].x1, stu[i].y1, stu[j].x2, stu[j].y2) || so(stu[i].x2, stu[i].y2, stu[j].x1, stu[j].y1) || so(stu[i].x2, stu[i].y2, stu[j].x2, stu[j].y2))
flag = 1;
}
if(flag) puts("Yes!");
else puts("No!");
}
return 0;
}
問題蟲洞——D: D - Intersecting Lines
黑洞內窺:
n組樣例,每組樣例給出兩條線段的座標,即八個點座標
問每組樣例的兩條線段是平行,重合還是相交
如果相交,請輸出交點。
思維光年:
枚舉兩條線段的所以情況;
ACcode:
//#include<bits/stdc++.h>
#include <stdio.h>
#include <iostream>
#include<algorithm>
#include <map>
#include <set>
//#include <vector>
//#include <queue>
//#include <stack>
#include <stdlib.h>
#include <cstring>
#include <string.h>
#include <string>
#include <math.h>
#include <sstream>
using namespace std;
typedef long long int ll;
const ll MAXN = 5005;
#define INF 0x3f3f3f3f//將近ll類型最大數的一半,而且乘2不會爆ll
const ll mod = 100000007;
const double eps = 0.0000001;
int main()
{
int t;
cin >> t;
puts("INTERSECTING LINES OUTPUT");
while(t--)
{
double x1, y1, x2, y2, x3, y3, x4, y4;
scanf("%lf %lf %lf %lf %lf %lf %lf %lf", &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4);
double a1=0, b1=0, a2=0, b2=0;
int f1 = 0, f2 = 0;//判斷線段1和2是否垂直x軸
if(x1 == x2) f1 = 1;//垂直無斜率
else {
a1 = (y2 - y1)/(x2 - x1);
b1 = y1 - a1*x1;
}
if(x3 == x4) f2 = 1;
else {
a2 = (y4 - y3)/(x4 - x3);
b2 = y3 - a2*x3;
}
if(f1 && f2 && x1!=x3) puts("NONE");
else if(f1 && f2 && x1 == x3) puts("LINE");
else if(f1 && !f2)
{
double x = x1;
double y = a2*x+b2;
printf("POINT %.2f %.2f\n", x, y);
}
else if(!f1 && f2)
{
double x = x3;
double y = a1*x+b1;
printf("POINT %.2f %.2f\n", x, y);
}
else if(!f1 && !f2 && fabs(a1-a2) < eps && fabs(b1-b2) < eps) puts("LINE");
else if(!f1 && !f2 && fabs(a1-a2) < eps && b1 != b2) puts("NONE");
else {
double x = (b2-b1)*1.0/(a1-a2);
double y = a1*x + b1;
printf("POINT %.2f %.2f\n", x, y);
}
}
puts("END OF OUTPUT");
return 0;
}
問題蟲洞——F: F - Pick-up sticks
黑洞內窺:
有n條木棍,編號爲1~n,按順序給出木棍的位置,
木棍之間相交則必有一條木棍在上面,求頂部木棍的編號。
思維光年:
把木棍想成線段,求n條線段相交,即線段交
ACcode:
//#include<bits/stdc++.h>
#include <stdio.h>
#include <iostream>
#include<algorithm>
//#include <map>
//#include <set>
//#include <vector>
//#include <queue>
//#include <stack>
#include <stdlib.h>
#include <cstring>
#include <string.h>
#include <string>
#include <math.h>
using namespace std;
typedef long long ll;
#define MAXN 100005
#define INF 0x3f3f3f3f//將近ll類型最大數的一半,而且乘2不會爆ll
struct point
{
double x,y;
};
struct line
{
point p1,p2;
} a[100010];
//叉乘
double chacheng(point p1,point p2,point p3)
{
return (p1.x-p3.x)*(p2.y-p3.y)-(p1.y-p3.y)*(p2.x-p3.x);
}
//判斷是否相交
int judge(line l1,line l2)
{
if( min(l2.p1.x,l2.p2.x)<=max(l1.p1.x,l1.p2.x)
&& min(l2.p1.y,l2.p2.y)<=max(l1.p1.y,l1.p2.y)
&& min(l1.p1.x,l1.p2.x)<=max(l2.p1.x,l2.p2.x)
&& min(l1.p1.y,l1.p2.y)<=max(l2.p1.y,l2.p2.y)
&& chacheng(l1.p1,l2.p2,l2.p1)*chacheng(l1.p2,l2.p2,l2.p1)<=0//這裏需要等於,因爲木棍可能堆疊起來。
&& chacheng(l2.p1,l1.p2,l1.p1)*chacheng(l2.p2,l1.p2,l1.p1)<=0 )
return 1;
else
return 0;
}
bool is[MAXN];
int main()
{
int n;
while(cin >> n && n)
{
memset(is, 0, sizeof(is));
for(int i=0; i<n; ++i)
scanf("%lf %lf %lf %lf", &a[i].p1.x, &a[i].p1.y, &a[i].p2.x, &a[i].p2.y);
for(int i=0; i<n-1; ++i)
for(int j=i+1; j<n; ++j)
if(judge(a[i], a[j]))
{
is[i] = 1;
break;
}
printf("Top sticks: ");
for(int i=0; i<n; ++i)
{
if(!is[i])
{
cout << i+1;
if(i == n-1)
cout << ".\n";
else
cout << ", ";
}
}
}
}
問題蟲洞——G: G - Treasure Hunt
黑洞內窺:
一個100*100的矩陣,中間有n條線段切割,每條線段代表一扇長長的門
然後給出一個寶藏的座標,從矩陣的外面穿過矩陣(矩陣算一層門)到寶藏,
每次只能走一段門的中點,求至少要經過多少扇門才能拿到寶藏。
思維光年:
中點不重要,又不是求最短路,,
我們要求的是破門的個數,直接暴力枚舉矩陣的邊界到寶藏這條線段與所有門的線段交。
取最小值++就綠了~~~~
ACcode:
//#include<bits/stdc++.h>
#include <stdio.h>
#include <iostream>
#include<algorithm>
//#include <map>
//#include <set>
//#include <vector>
//#include <queue>
//#include <stack>
#include <stdlib.h>
#include <cstring>
#include <string.h>
#include <string>
#include <math.h>
using namespace std;
typedef long long ll;
#define MAXN 100005
#define INF 0x3f3f3f3f//將近ll類型最大數的一半,而且乘2不會爆ll
struct point
{
double x,y;
};
struct line
{
point p1,p2;
} a[50], cf;
double chacheng(point p1,point p2,point p3)
{
return (p1.x-p3.x)*(p2.y-p3.y)-(p1.y-p3.y)*(p2.x-p3.x);
}
int judge(line l1,line l2)//線段ll和線段l2是否相交
{
if( min(l2.p1.x, l2.p2.x)<=max(l1.p1.x, l1.p2.x)
&& min(l2.p1.y, l2.p2.y)<=max(l1.p1.y, l1.p2.y)
&& min(l1.p1.x, l1.p2.x)<=max(l2.p1.x, l2.p2.x)
&& min(l1.p1.y, l1.p2.y)<=max(l2.p1.y, l2.p2.y)
&& chacheng(l1.p1, l2.p2, l2.p1)*chacheng(l1.p2, l2.p2, l2.p1)<0//這裏不能相等,否則你會wa到枯的~~~~,,,因爲如果門重合了,你就不可能走這扇門了。
&& chacheng(l2.p1, l1.p2, l1.p1)*chacheng(l2.p2, l1.p2, l1.p1)<0)
return 1;
return 0;
}
int main()
{
int n;
cin >> n;
if(n == 0)
puts("Number of doors = 1");
else
{
for(int i=0; i<n; ++i)
scanf("%lf %lf %lf %lf", &a[i].p1.x, &a[i].p1.y, &a[i].p2.x, &a[i].p2.y);
scanf("%lf %lf", &cf.p2.x, &cf.p2.y);
int ans = INF;
for(int i=1; i<=100; ++i)
{
cf.p1.x = 0.0, cf.p1.y = i*1.0;
int tot = 0;
for(int j=0; j<n; ++j)
{
if(judge(cf, a[j]))
tot++;
}
ans = min(ans, tot);
cf.p1.x = 100.0, cf.p1.y = i*1.0;
tot = 0;
for(int j=0; j<n; ++j)
{
if(judge(cf, a[j]))
tot++;
}
ans = min(ans, tot);
cf.p1.x = i*1.0, cf.p1.y = 0.0;
tot = 0;
for(int j=0; j<n; ++j)
{
if(judge(cf, a[j]))
tot++;
}
ans = min(ans, tot);
cf.p1.x = i*1.0, cf.p1.y = 100.0;
tot = 0;
for(int j=0; j<n; ++j)
{
if(judge(cf, a[j]))
tot++;
}
ans = min(ans, tot);
if(ans == 0)
break;
}
cout << "Number of doors = " << ans+1 << '\n';
}
return 0;
}
問題蟲洞——H: H - Intersection
黑洞內窺:
輸入四個點,前兩點確定一條線段,
後兩點確定一個矩陣,讓你判斷矩陣和線段的關係。
若相交輸出T,否則輸出F
思維光年:
線段和矩陣相交的條件:
1、線段在矩陣內;
2、線段和矩陣的邊有交點
ACcode:
//#include<bits/stdc++.h>
#include <stdio.h>
#include <iostream>
#include<algorithm>
//#include <map>
//#include <set>
//#include <vector>
//#include <queue>
//#include <stack>
#include <stdlib.h>
#include <cstring>
#include <string.h>
#include <string>
#include <math.h>
using namespace std;
typedef long long ll;
#define MAXN 100005
#define INF 0x3f3f3f3f//將近ll類型最大數的一半,而且乘2不會爆ll
struct point
{
double x,y;
};
struct line
{
point p1,p2;
} a[5], cf;
double chacheng(point p1,point p2,point p3)
{
return (p1.x-p3.x)*(p2.y-p3.y)-(p1.y-p3.y)*(p2.x-p3.x);
}
int judge(line l1,line l2)//線段ll和線段l2是否相交
{
if( min(l2.p1.x, l2.p2.x)<=max(l1.p1.x, l1.p2.x)
&& min(l2.p1.y, l2.p2.y)<=max(l1.p1.y, l1.p2.y)
&& min(l1.p1.x, l1.p2.x)<=max(l2.p1.x, l2.p2.x)
&& min(l1.p1.y, l1.p2.y)<=max(l2.p1.y, l2.p2.y)
&& chacheng(l1.p1, l2.p2, l2.p1)*chacheng(l1.p2, l2.p2, l2.p1)<=0//判斷在同一點的兩側
&& chacheng(l2.p1, l1.p2, l1.p1)*chacheng(l2.p2, l1.p2, l1.p1)<=0)
return 1;
return 0;
}
double xx[2], yy[2];
int main()
{
int t;
cin >> t;
while(t--)
{
memset(a, 0, sizeof(a));
scanf("%lf %lf %lf %lf %lf %lf %lf %lf", &cf.p1.x, &cf.p1.y, &cf.p2.x, &cf.p2.y, &xx[0], &yy[0], &xx[1], &yy[1]);
sort(xx, xx+2); sort(yy, yy+2);//存矩陣的邊
a[0].p1.x = xx[0], a[0].p1.y = yy[0];
a[0].p2.x = xx[1], a[0].p2.y = yy[0];
a[1].p1.x = xx[0], a[1].p1.y = yy[0];
a[1].p2.x = xx[0], a[1].p2.y = yy[1];
a[2].p1.x = xx[1], a[2].p1.y = yy[1];
a[2].p2.x = xx[1], a[2].p2.y = yy[0];
a[3].p1.x = xx[1], a[3].p1.y = yy[1];
a[3].p2.x = xx[0], a[3].p2.y = yy[1];
if(xx[0]<=cf.p1.x && cf.p1.x <= xx[1] && xx[0]<=cf.p2.x && cf.p2.x <= xx[1] && yy[0]<=cf.p1.y && cf.p1.y <= yy[1] && yy[0]<=cf.p2.y && cf.p2.y <= yy[1])
puts("T");
else
{
int tot=0;
for(int i=0; i<4; ++i)
if(judge(cf, a[i]))
tot++;
if(tot) puts("T");
else puts("F");
}
}
return 0;
}