สมมติว่าเรามีรายการจุดที่เป็นรูปหลายเหลี่ยมเมื่อเชื่อมติดกันตามลำดับ เราต้องค้นหาว่ารูปหลายเหลี่ยมนี้นูนหรือไม่ (นิยามรูปหลายเหลี่ยมนูน) เราต้องจำไว้ว่ามีอย่างน้อย 3 และสูงสุด 10,000 คะแนน และพิกัดอยู่ในช่วง -10,000 ถึง 10,000
เราสามารถสมมติได้ว่ารูปหลายเหลี่ยมที่เกิดจากจุดที่กำหนดให้เป็นรูปหลายเหลี่ยมธรรมดาเสมอ กล่าวคือ เราตรวจสอบให้แน่ใจว่าขอบทั้งสองตัดกันที่จุดยอดแต่ละจุด และขอบนั้นจะไม่ตัดกัน ดังนั้นหากอินพุตมีลักษณะดังนี้:[[0,0],[0,1],[1,1],[1,0]] จะเป็นนูน ดังนั้นค่าที่ส่งคืนจะเป็นจริง
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
กำหนดวิธีการ calc() ซึ่งจะใช้ ax, ay, bx, by, cx, cy ซึ่งจะทำงานดังนี้ -
-
BAx :=axe – bx, BAy :=ay – โดย, BCx :=cx – bx, BCy :=cy - โดย
-
จากวิธีหลักให้ทำดังนี้
-
neg :=false และ pos :=false, n :=ขนาดของ point array
-
สำหรับฉันอยู่ในช่วง 0 ถึง n – 1
-
a :=i, b :=(i + 1) mod n และ c :=(i + 2) mod n
-
cross_prod :=calc(p[a, 0], p[a, 1], p[b, 0], p[b, 1], p[c, 0], p[c, 1])
-
ถ้า cross_prod <0 แล้ว neg :=true มิฉะนั้นเมื่อ cross_prod> 0 แล้ว pos :=true
-
ถ้า neg และ pos เป็นจริง ให้คืนค่าเท็จ
-
-
คืนความจริง
ตัวอย่าง (C++)
ให้เราดูการใช้งานต่อไปนี้เพื่อทำความเข้าใจ −
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
bool isConvex(vector<vector<int>>& points) {
bool neg = false;
bool pos = false;
int n = points.size();
for(int i = 0; i < n; i++){
int a = i;
int b = (i + 1) % n;
int c = (i + 2) % n;
int crossProduct = calc(points[a][0], points[a][1], points[b][0], points[b][1], points[c][0], points[c][1]);
if(crossProduct < 0) neg = true;
else if(crossProduct > 0) pos = true;
if(neg && pos) return false;
}
return true;
}
int calc(int ax, int ay, int bx, int by, int cx, int cy){
int BAx = ax - bx;
int BAy = ay - by;
int BCx = cx - bx;
int BCy = cy - by;
return (BAx * BCy - BAy * BCx);
}
};
main(){
vector<vector<int>> v = {{0,0},{0,1},{1,1},{1,0}};
Solution ob;
cout << (ob.isConvex(v));
} อินพุต
[[0,0],[0,1],[1,1],[1,0]]
ผลลัพธ์
1