1. 程式人生 > >JZYZOJ1535 [haoi2014]穿越封鎖線

JZYZOJ1535 [haoi2014]穿越封鎖線

using view size closed n) algorithm style 一段 ios

http://172.20.6.3/Problem_Show.asp?id=1535

整體來說是道水題,但是穿過點的判定把我坑得wa了兩次,考場上這可是40分的水分啊啊啊。

開始的錯誤想法:排序後向上掃一遍,通過邊就轉換加或不加這一段的狀態,通過點就不轉換。
錯誤想法沒有考慮到折點而非轉點的情況。
正確想法與錯誤的只有點的判定不同:點的判定是如果這個點連接的兩條邊是在穿越線的一側,則通過這點後加或不加的狀態不變,否則轉換。

還是邏輯太弱。

代碼

技術分享
 1 #include<iostream>  
 2 #include<cstdio>  
 3 #include<cstring>  
 4
#include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #define lc x*2 8 #define rc x*2+1 9 using namespace std; 10 const int maxn=110; 11 int n,x,y; 12 int a[maxn]={}; 13 int b[maxn]={}; 14 struct wtf{ 15 double y; 16 bool f; 17 }e[maxn]; 18 int tot=0; 19 bool mmp(wtf xx,wtf yy){
20 return xx.y<yy.y; 21 } 22 int main(){ 23 scanf("%d",&n); 24 for(int i=1;i<=n;i++){ 25 scanf("%d%d",&a[i],&b[i]); 26 }a[0]=a[n];b[0]=b[n]; 27 scanf("%d%d",&x,&y);int x1,x2,y1,y2; 28 for(int i=1;i<=n;i++){ 29 if(a[i]==x){ 30 e[++tot].y=b[i];e[tot].f=0
; 31 if((a[i-1]-a[i])*(a[i+1]-a[i])>0) e[tot].f=1; 32 } 33 if((a[i]-x)*(a[i-1]-x)<0){ 34 if(a[i]>a[i-1]){x1=a[i-1],x2=a[i],y1=b[i-1],y2=b[i];} 35 else {x1=a[i],x2=a[i-1],y1=b[i],y2=b[i-1];} 36 e[++tot].y=double(y2-y1)/(x2-x1)*(x-x1)+y1; 37 e[tot].f=0; 38 } 39 } 40 sort(e+1,e+1+tot,mmp); 41 double cnt=0,z;int f=1; 42 if(e[1].f)f=0; 43 for(int i=2;i<=tot;i++){ 44 if(f&&e[i].y>y){ 45 if(y>e[i-1].y)z=y; 46 else z=e[i-1].y; 47 cnt+=e[i].y-z; 48 } 49 if(!e[i].f)f=f^1; 50 51 }int ans=cnt; 52 printf("%d\n",ans); 53 return 0; 54 }
View Code

JZYZOJ1535 [haoi2014]穿越封鎖線