• bzoj1074【Scoi2007】折纸
    • 思路:考虑倒着做,每次将在折叠的直线右边的扔掉,左边的点再对称一次加入;
    • 算几知识:求向量关于法向量的对称向量
    • 点$A$关于点$B$对称的点$C = 2B - A$
    • 如果要求$\vec{A}$关于法向量$\vec{l}$的对称向量$\vec{A'}$;
    • 可以考虑都平移到原点
    • 利用点积求出$\vec{A}$在$\vec{l}$上的投影点$D$, 再将点$A$关于$D$对称到$A'$;
    • $A'$的坐标就是向量$\vec{A'}$
    •  1 #include<bits/stdc++.h>
       2 #define db double
       3 #define eps 1e-6
       4 using namespace std;
       5 const int N=1<<9;
       6 int n,m,cnt,tmp;
       7 int dcmp(db x){return fabs(x)<=eps?0:x<0?-1:1;}
       8 struct point{
       9     db x,y;
      10     point(db _x=0,db _y=0):x(_x),y(_y){};
      11     point operator +(const point&A)const{return point(x+A.x,y+A.y);}
      12     point operator -(const point&A)const{return point(x-A.x,y-A.y);}
      13     point operator *(const db&a)const{return point(x*a,y*a);}
      14     db operator *(const point&A)const{return x*A.x+y*A.y;}
      15     db operator ^(const point&A)const{return x*A.y-y*A.x;}
      16 }p1[N],p2[N],q[N],qq[N];
      17 bool onleft(point A,point B,point C){
      18     return dcmp((C-B)^(A-B))>0;
      19 }
      20 point rev(point A,point B,point C){
      21     point D = C - B; 
      22     db l2 = D*D;
      23     D = B + D*((A-B)*D/l2);
      24     return D*2 - A;
      25 }
      26 int main(){
      27     #ifndef ONLINE_JUDGE
      28     freopen("bzoj1074.in","r",stdin);
      29     freopen("bzoj1074.out","w",stdout);
      30     #endif 
      31     scanf("%d", &n);
      32     for(int i=1;i<=n;i++)scanf("%lf%lf%lf%lf", &p1[i].x, &p1[i].y, &p2[i].x, &p2[i].y);
      33     scanf("%d", &m);
      34     for(int i=1;i<=m;i++){
      35         cnt=1;scanf("%lf%lf", &q[1].x, &q[1].y);
      36         for(int j=n;j;j--){
      37             tmp=0;
      38             for(int k=1;k<=cnt;k++)if(onleft(q[k],p1[j],p2[j])){
      39                 qq[++tmp] = q[k];
      40                 qq[++tmp] = rev(q[k],p1[j],p2[j]);
      41             }
      42             cnt=tmp;
      43             if(!cnt)break;
      44             for(int k=1;k<=cnt;k++)q[k]=qq[k];
      45         }
      46         int ans=0;
      47 //        puts("");
      48         for(int j=1;j<=cnt;j++){
      49 //            printf("%.2f %.2lf\n",q[j].x, q[j].y);
      50             if(dcmp(q[j].x)>0&&dcmp(q[j].y)>0&&dcmp(100-q[j].x)>0&&dcmp(100-q[j].y)>0){
      51                 ans ++;
      52             }
      53         }
      54         printf("%d\n",ans);
      55     }
      56     return 0;
      57 }
      bzoj1074

相关文章: