1. 程式人生 > 實用技巧 >6818. 【2020.10.07提高組模擬】數列遞推

6818. 【2020.10.07提高組模擬】數列遞推

題目連結:https://vjudge.net/problem/POJ-1265

題意:機器人剛開始在原點,然後有n次指令,每次指令機器人的座標會變成(x,y),機器人是按直線走到下一個點,第n次指令後,機器人會回到原點,機器人的路徑是一個凸多邊形,要你求這個凸多邊形內的整點數,邊上的點數,以及面積。

思路:對於一個凸多邊形的面積可以用差積來求。以整點為頂點的線段,覆蓋的點的個數為 gcd(dx,dy),其中dx,dy分別為線段橫向佔的點數和縱向佔的點數。如果 dx或 dy為0,則覆蓋的點數為 xy或dx。然後凸多邊行內的整數點可以根據pick定理來求。

pick定理:S=x+d/2-1;S是多邊形的面積,x是內部的整數點,d是邊上的整數點。

#include<bits/stdc++.h>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
    int x,y;
}a[205];
int chaj(int x1,int y1,int x2,int y2)
{
    return
x1*y2-x2*y1; } int gcd(int x,int y) { while(y) { int z=x%y; x=y; y=z; } return x; } int main() { int t,u=0; cin>>t; while(t--) { int n; cin>>n; a[0].x=a[0].y=0; for(int i=1;i<=n;i++) { cin
>>a[i].x>>a[i].y; a[i].x+=a[i-1].x; a[i].y+=a[i-1].y; } int ans=0; for(int i=1;i<=n;i++) ans+=chaj(a[i-1].x,a[i-1].y,a[i].x,a[i].y); ans=abs(ans); int sum=0; for(int i=1;i<=n;i++) sum+=gcd(abs(a[i].x-a[i-1].x),abs(a[i].y-a[i-1].y)); //sum+=gcd(abs(a[n].x-a[1].x),abs(a[n].y-a[1].y)); int x=ans+2-sum; x/=2; double s=ans/2.0; printf("Scenario #%d:\n",++u); printf("%d %d %.1lf\n\n",x,sum,s); } }