又是暴力破解的一天
而且還是個數學渣
剛看到這一題的時候真的崩潰,稍微列了一下公式後好一點,但又發現按這種解法情況太多
但是自己分的情況跪着也要分完
下面先列一下思路:我採用的是最普通的點斜式方程
-
計算兩根直線斜率,判斷兩根線段的斜率是否存在
-
都存在
-
判斷是否平行
-
平行但不重合
-
此時一定沒有交點,返回空數組
-
-
重合
-
判斷哪一部分重合並返回題目中所要求的最小點
-
-
不平行
- 計算出兩根直線的點斜式方程
- 計算兩根直線交點,並判斷交點是否在兩根線段範圍內
-
-
-
有一根不存在(垂直於x軸)
-
直線一定重合,但線段不一定重合
-
計算斜率存在那根直線的點斜式方程
-
計算直線交點,並判斷交點是否在兩根線段範圍內
-
-
兩根都不存在(兩根都垂直於x軸)
-
只可能平行或者重合
-
判斷是否重合
-
重合,則判斷哪一部分重合並返回題目中所要求的最小點
-
平行,返回空數組
-
-
-
下面是在提交過程中修改了很多次的代碼...
代碼能力是挺差勁的,就看看思路吧(也沒啥好看的)
提交時修改的幾個點:
1. 計算k(斜率)時,要先強轉成double,否則int類型會出錯
2. double類型是存在infinity類型的,所以要判斷,直接是拋不出異常的
3. 判斷交點是否在線段內時不要忘記等號
最後結果是(我盡力了):
執行用時 :8 ms, 在所有 Java 提交中擊敗了18.52%的用戶
內存消耗 :39 MB, 在所有 Java 提交中擊敗了100.00%的用戶
public static double[] intersection(int[] start1, int[] end1, int[] start2, int[] end2) {
//計算k1 k2
double x_res = 0;
double y_res = 0;
try {
//k1 k2均存在
double k1 = (double)(end1[1] - start1[1])/(double)(end1[0] - start1[0]);
if(k1 == Double.POSITIVE_INFINITY || k1 == Double.NEGATIVE_INFINITY) {
throw new Exception();
}
double b1 = start1[1] - k1*start1[0];
double k2 = (double)(end2[1] - start2[1])/(double)(end2[0] - start2[0]);
double b2 = start2[1] - k2*start2[0];
if(k1 == k2 && b1==b2) { //重合但不一定相交
if(Math.min(start2[0],end2[0]) >= Math.min(start1[0], end1[0]) && Math.min(start2[0],end2[0]) <= Math.max(start1[0], end1[0])) {
return new double[] {Math.min(start2[0],end2[0]), Math.min(start2[0],end2[0])*k1+b1};
} else if(Math.max(start2[0],end2[0]) >= Math.min(start1[0], end1[0]) && Math.max(start2[0],end2[0]) <= Math.max(start1[0], end1[0])) {
return new double[] {Math.min(start1[0],end1[0]), Math.min(start1[0],end1[0])*k1+b1};
} else {
return new double[] {};
}
}
else if (k1 == k2 && b1 != b2) //平行
{
return new double[] {};
} else { //既不平行也不重合
x_res = (b1-b2)/(k2-k1);
y_res = k1*x_res + b1;
System.out.println(x_res + " " + y_res);
if(x_res >= Math.min(start1[0], end1[0]) && x_res <= Math.max(start1[0], end1[0]) && y_res <= Math.max(start2[1], end2[1]) && y_res >= Math.min(start2[1], end2[1])) { //有交點
return new double[] {x_res, y_res};
} else {
return new double[] {};
}
}
} catch (Exception e) { //k1爲無窮大 第一條線段爲x=start1[0]
// System.out.println("k1true");
x_res = start1[0];
try { //可能有交點
double k2 = (double)(end2[1] - start2[1])/(double)(end2[0] - start2[0]);
if(k2 == Double.POSITIVE_INFINITY || k2 == Double.NEGATIVE_INFINITY) {
throw new Exception();
}
double b2 = start2[1] - k2*start2[0];
if(x_res >= Math.min(start1[0], end1[0]) && x_res <= Math.max(start1[0], end1[0])) { //有交點
y_res = k2*x_res + b2;
return new double[] {x_res, y_res};
} else { //無交點
return new double[] {};
}
} catch (Exception e2) { //兩條線段都垂直於x軸
if(x_res == start2[0]) { //重合
// System.out.println(true);
// System.out.println(Math.min(start2[1],end2[1]));
if(Math.min(start2[1],end2[1]) >= Math.min(start1[1], end1[1]) && Math.min(start2[1],end2[1]) <= Math.max(start1[1], end1[1])) {
return new double[] {x_res, Math.min(start2[1],end2[1])};
} else if(Math.max(start2[1],end2[1]) >= Math.min(start1[1], end1[1]) && Math.max(start2[1],end2[1]) <= Math.max(start1[1], end1[1])) {
return new double[] {x_res, Math.min(start1[1],end1[1])};
} else {
return new double[] {};
}
} else { //沒有交點
return new double[] {};
}
}
}
}