標籤:blog http os io for 資料 ar div log
http://cojs.tk/cogs/problem/problem.php?pid=896
我的計算幾何入門題。。。
看了看白書的計算幾何部分,,恩好嘛。。
乃們都用向量!!!!
幹嘛非要將2個點確定一條線變成一個點從原點o出發的射線!!!!
這就是所謂的玩概念嗎
然後用所謂的向量加減,是這些向量起點相同,然後就變成了原點o出發的射線!!!
然後你們還在玩概念!我跪了。
(以上純屬蒟蒻吐槽)
好吧,計算幾何非常有用的。。簡化了不少操作。
這裡還有啥點積啥叉積。點積就是同一起點的向量(終點)的 x座標乘積+y座標乘積,,,,叉積就是同一起點的向量(終點)的 x座標和y座標交叉乘起來的差。。
噗。。真帥!!
計算幾何好神奇啊!!
簡化了好多操作!!!
我發現我愛上他了!!
(吐槽完畢)
會到此題。。。裸的凸包。。
白書上有,我就不說了,,就是掃過去判斷叉積正負,也就是說在向量左邊還是右邊,在左邊就繼續,在右邊就退棧重來。
#include <cstdio>#include <cstring>#include <cmath>#include <string>#include <iostream>#include <algorithm>#include <string>using namespace std;#define rep(i, n) for(int i=0; i<(n); ++i)#define for1(i,a,n) for(int i=(a);i<=(n);++i)#define for2(i,a,n) for(int i=(a);i<(n);++i)#define for3(i,a,n) for(int i=(a);i>=(n);--i)#define for4(i,a,n) for(int i=(a);i>(n);--i)#define CC(i,a) memset(i,a,sizeof(i))#define read(a) a=getint()#define print(a) printf("%d", a)#define dbg(x) cout << #x << " = " << x << endl#define printarr(a, n, m) rep(aaa, n) { rep(bbb, m) cout << a[aaa][bbb]; cout << endl; }inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<‘0‘||c>‘9‘; c=getchar()) if(c==‘-‘) k=-1; for(; c>=‘0‘&&c<=‘9‘; c=getchar()) r=r*10+c-‘0‘; return k*r; }inline const int max(const int &a, const int &b) { return a>b?a:b; }inline const int min(const int &a, const int &b) { return a<b?a:b; }using namespace std;void setio(string name){string in = name + ".in", out = name + ".out";ios::sync_with_stdio(false);freopen(in.c_str(), "r", stdin);freopen(out.c_str(), "w", stdout);}const int N=10005;struct node { double x, y; node(const double &_x=0, const double &_y=0) : x(_x), y(_y) {}}st[N], p[N];int cnt, n;node operator - (const node &a, const node &b) { return node(a.x-b.x, a.y-b.y); }double cross(const node &a, const node &b) { return a.x*b.y-b.x*a.y; }const bool cmp(const node &a, const node &b) { return (a.x==b.x)?(a.y<b.y):(a.x<b.x); }const double dis(const node &a, const node &b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); }void tubao() {sort(p, p+n, cmp);cnt=0;rep(i, n) {while(cnt>1 && cross(st[cnt-1]-st[cnt-2], p[i]-st[cnt-2])<=0) --cnt;st[cnt++]=p[i];}int k=cnt;for3(i, n-2, 0) {while(cnt>k && cross(st[cnt-1]-st[cnt-2], p[i]-st[cnt-2])<=0) --cnt;st[cnt++]=p[i];}if(n>1) --cnt;}int main() {setio("fc");scanf("%d", &n);rep(i, n) scanf("%lf%lf", &p[i].x, &p[i].y);tubao();double ans=0;for1(i, 0, cnt-1) ans+=dis(st[i], st[i+1]);printf("%.2lf\n", ans);return 0;}
描述
農夫約翰想要建造一個圍欄用來圍住他的奶牛,可是他資金匱乏。他建造的圍欄必須包括他的奶牛喜歡吃草的所有地點。對於給出的這些地點的座標,計算最短的能夠圍住這些點的圍欄的長度。
PROGRAM NAME: fcINPUT FORMAT(file fc.in)
輸入資料的第一行包括一個整數 N。N(0 <= N <= 10,000)表示農夫約翰想要圍住的放牧點的數目。接下來 N 行,每行由兩個實數組成,Xi 和 Yi,對應平面上的放牧點座標(-1,000,000 <= Xi,Yi <= 1,000,000)。數字用小數表示。
OUTPUT FORMAT(file fc.out)
輸出必須包括一個實數,表示必須的圍欄的長度。答案保留兩位小數。
SAMPLE INPUT (file fc.in)
44 84 125 9.37 8
SAMPLE OUTPUT (file fc.out)
12.00
【COGS & USACO】896. 圈奶牛(凸包)