[Offer收割]程式設計練習賽2 hihocoder 1275 掃地機器人 (計算幾何+模擬 比較煩)
描述
小Ho最近買了一臺掃地機器人用來代替他清掃實驗室的衛生,掃地機器人有不同的尺寸,但是通常來說可以被視作一個M*M的正方形,掃地機器人僅能清掃被自己覆蓋過的區域。
小Ho所在的實驗室是一個多邊形,任意兩條邊之間要麼為垂直關係要麼為平行關係。掃地機器人也僅能沿著這兩個方向平移,不能旋轉。實驗室中的一些區域過於狹窄,所以對掃地機器人的大小就有了限制。
於是小Ho找到了你,給出實驗室的地形和掃地機器人的大小,希望你能夠判斷給定的掃地機器人能否成功清掃實驗室的每一塊區域。
輸入
每個輸入檔案包含多組測試資料,在每個輸入檔案的第一行為一個整數Q,表示測試資料的組數。
每組測試資料的第一行為兩個正整數N和M,分別表示多邊形的點數和機器人的大小。
接下來的N行,每行為兩個整數X、Y,表示多邊形的一個頂點。
多邊形的頂點按照“順時針”順序給出,即從當前點前往下一個點時,多邊形的“內部”在右側方向,多邊形的邊均平行於座標軸。
對於20%的資料,滿足0<=N<=200,1<=X、Y、M<=100
對於100%的資料,滿足0<=N<=1000,1<=X、Y、M<=108
對於100%的資料,滿足實驗室可以由一個1*1的掃地機器人完成清掃。
對於100%的資料,滿足Q<=5
輸出
對於每組測試資料,如果機器人能夠順利完成任務,輸出Yes,否則輸出No。
樣例提示
樣例1(x軸正方向為向下,y軸正方向為向右):
樣例3(x軸正方向為向下,y軸正方向為向右):
3
6 2
0 0
0 2
2 2
2 3
3 3
3 0
6 2
0 0
0 3
3 3
3 5
5 5
5 0
8 2
0 0
0 2
1 2
1 3
3 3
3 1
2 1
2 0
樣例輸出
No
Yes
No
題目連結:http://hihocoder.com/problemset/problem/1275
題目分析:首先先%一下比賽時的滿分選手,再吐槽一下直接找邊平方最小與m方判斷都能得70分的資料。。。
這題做了好久。。。中間過程比較煩,這題的大體思路是模擬,即從起點開始按輸入順序(順時針)讓機器人沿著多邊形的內邊走,每走一條邊判斷一下首先要處理知道一條邊和下一個點怎麼判斷往哪個方向轉的問題,先設三個點p1(當前線的起點),p2(當前線的終點),p3(下一個點)為了求方向我們把它們定義為空間中的三點p1(x1, y1, 0),p2(x2, y2, 0),p3(x3, y3, 0)
那麼向量p1->p2表示為α=(x2-x1, y2-y1, 0),向量p2->p3表示為β=(x3-x2, y3-y2, 0),α×β (×為叉乘)得到f = (x1-x3)*(y2-y3)-(x2-x3)*(y1-y3)
根據右手定則,f>0時右轉,f<0時左轉。因此我們可以先算出機器人繞多邊形一圈的整個轉向過程,1表示右轉,0表示左轉,由於回到起點時起點也要判斷,因此把第二個點作為最後一個點。由於我們是按照輸入順序即順時針方向貼邊內側走,因此可以發現,每次到一個角時,如果是向右轉則必定在內角,否則在外角,如下圖:
之後對於每個角算出機器人所要佔據的面積再列舉每一條線,判斷是否有線穿過機器人,有則無解,不衝突的情況共8種,如下圖:
開始用了騙分的那種思路做特判其實也是不對的,比如這種圖形
短邊為1,長邊為2,顯然用邊長為2的機器人是可以全部打掃到的
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#define ll long long
using namespace std;
int const MAX = 1e3 + 5;
int n, m;
int dir[MAX]; //0左,1右
struct POINT
{
int x, y;
}p[MAX];
struct LINE
{
POINT s, e;
}l[MAX];
struct ROBOT
{
int x1, y1, x2, y2;
};
int Dir(POINT p1, POINT p2, POINT p3) // 1:右
{
if((ll)(p1.x - p3.x) * (p2.y - p3.y) < (ll)(p2.x - p3.x) * (p1.y - p3.y))
return 1;
return 0;
}
bool OK(ROBOT r, LINE a)
{
if(a.s.x < 0 || a.s.y < 0 || a.e.x < 0 || a.e.y < 0)
return true;
int min_x = min(a.s.x, a.e.x);
int max_x = max(a.s.x, a.e.x);
int min_y = min(a.s.y, a.e.y);
int max_y = max(a.s.y, a.e.y);
if(a.s.x == a.e.x)
if((a.s.x <= r.x1 && a.s.x <= r.x2) || (a.s.x >= r.x1 && a.s.x >= r.x2) || max_y <= r.y1 || min_y >= r.y2)
return false;
if(a.s.y == a.e.y)
if((a.s.y <= r.y1 && a.s.y <= r.y2) || (a.s.y >= r.y1 && a.s.y >= r.y2) || max_x <= r.x1 || min_x >= r.x2)
return false;
return true;
}
int main()
{
int T;
while(scanf("%d", &T) != EOF)
{
while(T --)
{
bool flag = true;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++)
scanf("%d %d", &p[i].x, &p[i].y);
p[n + 1] = p[1];
p[n + 2] = p[2];
for(int i = 1; i <= n && flag; i++)
{
l[i].s = p[i];
l[i].e = p[i + 1];
}
for(int i = 1; i <= n; i++)
dir[i] = Dir(l[i].s, l[i].e, p[i + 2]);
for(int i = 1; i <= n && flag; i++)
{
ROBOT a;
a.x1 = a.x2 = l[i].e.x;
a.y1 = a.y2 = l[i].e.y;
int dx = l[i].e.x - l[i].s.x;
int dy = l[i].e.y - l[i].s.y;
if(dir[i] == 1) //內角向右
{
if(dx > 0)
{
a.x1 -= m;
a.y1 -= m;
}
if(dx < 0)
{
a.x2 += m;
a.y2 += m;
}
if(dy > 0)
{
a.x2 += m;
a.y1 -= m;
}
if(dy < 0)
{
a.x1 -= m;
a.y2 += m;
}
}
else
{
if(dx > 0) //外角向左
{
a.x2 += m;
a.y1 -= m;
}
if(dx < 0)
{
a.x1 -= m;
a.y2 += m;
}
if(dy > 0)
{
a.x2 += m;
a.y2 += m;
}
if(dy < 0)
{
a.x1 -= m;
a.y1 -= m;
}
}
for(int i = 1; i <= n && flag; i++)
if(OK(a, l[i])) //true表示有交叉
flag = false;
}
printf("%s\n", flag ? "Yes" : "No");
}
}
}
相關文章
- [Offer收割]程式設計練習賽2 hihocoder 1273 (DFS + 狀壓)程式設計
- [Offer收割]程式設計練習賽1 hihocoder 1268 九宮 (DFS)程式設計
- [Offer收割]程式設計練習賽1 hihocoder 1270 建造基地 (完全揹包)程式設計
- [Offer收割]程式設計練習賽2 hihocoder 1272 買零食 (DFS 或 dp 水題)程式設計
- [Offer收割]程式設計練習賽1 hihocoder 1271 艦隊遊戲 (狀態壓縮+貪心 好題)程式設計遊戲
- [Offer收割]程式設計練習賽1 hihocoder 1269 優化延遲 (二分+優先權佇列)程式設計優化佇列
- 排球比賽計分程式模擬衝刺(sprint)
- 計算幾何
- 乒乓球比賽計分程式模擬衝刺(Sprint)計劃
- 【學習筆記】計算幾何筆記
- 團體程式設計天梯賽-練習集程式設計
- 程式設計假期練習題--2程式設計
- 山東省第四屆ACM大學生程式設計競賽-Rescue The Princess(計算幾何)ACM程式設計
- 計算幾何:模板
- 計算幾何模板
- 幾種計算圓周率的軟體比較
- 2017本科組模擬賽(計算生日)
- 程式設計練習程式設計
- [筆記] 計算幾何筆記
- 國外程式設計師為何練習中國氣功程式設計師
- 邊緣計算、霧計算、雲端計算區別幾何?
- 【比賽】暑假集訓CSP提高模擬2
- 【計算幾何】向量表示
- 【總結】計算幾何模板
- 二維計算幾何模板
- 【計算幾何】線段相交
- 三維計算幾何模板
- Something about 計算幾何
- 計算機視覺—圖片幾何變換(2)計算機視覺
- NOIP模擬賽2
- 計算幾何_向量的實現
- 【計算幾何】多邊形交集
- 計算幾何——平面最近點對
- 雲端計算與網格計算的深入比較
- 標準成本計算和平均成本計算比較
- Python 程式設計練習Python程式設計
- 程式設計師該知道的那些程式設計比賽網站程式設計師網站
- WebGPU 計算管線、計算著色器(通用計算)入門案例:2D 物理模擬WebGPU