bzoj 1100 [POI2007]對稱軸osi manacher
阿新 • • 發佈:2018-04-14
return 小朋友 min 他還 大腦 set truct 光明 com
Submit: 771 Solved: 307
[Submit][Status][Discuss]
老師布置了非常多的尋找多邊形的對稱軸的題,足夠她做相當長的一段時間了。在此之前FGD已經決定去海邊度過
這個難得的假期,不過他還是覺得應該幫助他的MM對付可愛的數學作業。很快地,他找到了解決方案,最好寫一個
程序來幫助yours檢查她的數學作業。因為FGD並非一個計算機科學家,所以他找到了他的好朋友你,請你幫助他完
成這個任務。請寫一個程序:讀入多邊形的描述計算出每個多邊形的對稱軸數將計算的結果輸出 00000000),依次表示多邊形的頂點坐標。多邊形不一定是凸的,但是不自交——任何兩條邊都只有最多一個公共
點——他們的公共端點。此外,沒有兩條連續的邊平行。
12
1 -1
2 -1
2 1
1 1
1 2
-1 2
-1 1
-2 1
-2 -1
-1 -1
-1 -2
1 -2
6
-1 1
-2 0
-1 -1
1 -1
2 0
1 1
2
[POI2007]對稱軸osi
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 771 Solved: 307
[Submit][Status][Discuss]
Description
FGD小朋友——一個聞名遐邇的年輕數學家——有一個小MM,yours。FGD小朋友非常喜歡他的MM,所以他很樂
意幫助他的MM做數學作業。但是,就像所有科學的容器一樣,FGD的大腦拒絕不停地重復思考同樣的問題。不幸的
是,yours是一個十分用功的學生,所以她不停地讓FGD幫助她檢查她的作業。一個陽光明媚的周末,yours的數學
這個難得的假期,不過他還是覺得應該幫助他的MM對付可愛的數學作業。很快地,他找到了解決方案,最好寫一個
程序來幫助yours檢查她的數學作業。因為FGD並非一個計算機科學家,所以他找到了他的好朋友你,請你幫助他完
成這個任務。請寫一個程序:讀入多邊形的描述計算出每個多邊形的對稱軸數將計算的結果輸出
Input
輸入的第一行包含一個正整數t(1<=t<=10),為多邊形的邊數。接下來,為t個多邊形的描述,每個描述的第一
行為一個正整數n(3<=n<=100000),表示了多邊形的點數。然後在後面n行每行兩個整數x和y(?100000000<=x, y<=1
點——他們的公共端點。此外,沒有兩條連續的邊平行。
Output
你的程序應該輸出正好t行,第k行包含了一個整數nk——表示第k個多邊形有多少個對稱軸。
Sample Input
212
1 -1
2 -1
2 1
1 1
1 2
-1 2
-1 1
-2 1
-2 -1
-1 -1
-1 -2
1 -2
6
-1 1
-2 0
-1 -1
1 -1
2 0
1 1
Sample Output
42
HINT
Source
題解:因為中心是原點,這個比較方便的了,然後發現對稱軸只有頂點處或者一條線段的中點處。
然後將相鄰的兩個頂點,相鄰的三個頂點,映射
把這個圖形寫成一個字符串的形式S,然後復制一遍SS,再用它的反串S‘跑一邊,看看能夠匹配多少次。答案就是多少了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<algorithm> 5 #include<cmath> 6 #include<cstring> 7 8 #define N 10000007 9 using namespace std; 10 inline int read() 11 { 12 int x=0,f=1;char ch=getchar(); 13 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 14 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 15 return x*f; 16 } 17 18 int n,m; 19 int s[N],f[N]; 20 struct Node 21 { 22 int x,y; 23 }a[N]; 24 25 int dis(int c,int b) 26 { 27 return (a[c].x-a[b].x)*(a[c].x-a[b].x)+(a[c].y-a[b].y)*(a[c].y-a[b].y); 28 } 29 int cro(int d,int b,int c) 30 { 31 return (a[b].x-a[d].x)*(a[c].y-a[d].y)-(a[c].x-a[d].x)*(a[b].y-a[d].y); 32 } 33 int main() 34 { 35 int T=read(); 36 while(T--) 37 { 38 n=read(); 39 for (int i=0;i<n;i++) 40 a[i].x=read(),a[i].y=read(); 41 for (int i=0;i<n;i++) s[i<<1|1]=dis(i,(i+1)%n); 42 for (int i=0;i<n;i++) s[i<<1]=cro(i,(i-1+n)%n,(i+1)%n); 43 int total=n<<1; 44 for (int i=0;i<n;i++) s[i+total]=s[i]; 45 total<<=1; 46 int ans=0,mx=0,id=0; 47 memset(f,0,sizeof(f)); 48 for (int i=0;i<total;i++) 49 { 50 if (mx>i) f[i]=min(mx-i,f[2*id-i]);else f[i]=1; 51 while(i-f[i]>=0&&i+f[i]<=total&&s[i-f[i]]==s[i+f[i]]) f[i]++; 52 if (i+f[i]>mx) mx=i+f[i],id=i; 53 if (f[i]>=n+1) ans++; 54 } 55 printf("%d\n",ans); 56 } 57 }
bzoj 1100 [POI2007]對稱軸osi manacher