zoukankan      html  css  js  c++  java
  • bzoj 1027: [JSOI2007]合金

    由于总和一定所以看前两个即可,可以他们抽象成平面上的点,两个点能合出来的点在以两点为端点的线段上,三个点的在以三点为顶点的三角形内,。。。

    所以预先处理那两个点的连线在所有被需要的点的一边,便把距离设为1,跑一遍最小环就行了。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<queue>
      7 #include<algorithm>
      8 #define M 509
      9 #define EPS 1e-10
     10 #define ll long long
     11 using namespace std;
     12 ll read()
     13 {
     14     char ch=getchar();
     15     ll x=0,f=1;
     16     for(;ch<'0'||ch>'9';ch=getchar())
     17         if(ch=='-')
     18           f=-1;
     19     for(;ch>='0'&&ch<='9';ch=getchar())
     20         x=x*10+ch-'0';
     21     return x*f;
     22 }
     23 int n,m,f[M][M],mx=707406378;
     24 struct data
     25 {
     26     double x,y;
     27 }a[M],b[M];
     28 data operator -(data a1,data a2)
     29 {
     30    data a3;
     31    a3.x=a1.x-a2.x;
     32    a3.y=a1.y-a2.y;
     33    return a3;
     34 }
     35 int jin(data a1,data a2)
     36 {
     37    double a3=a1.x*a2.y-a1.y*a2.x;
     38    if(a3>EPS)
     39       return 1;
     40    if(a3<-EPS)
     41       return -1;
     42    return 0;
     43 }
     44 int cheng(data a1,data a2)
     45 {
     46   double a3=a1.x*a2.x+a1.y*a2.y;
     47    if(a3>EPS)
     48       return 1;
     49    if(a3<-EPS)
     50       return -1;
     51    return 0;
     52 }
     53 bool pan1()
     54 {
     55   for(int i=1;i<=n;i++)
     56     {
     57       int sum=0;
     58       for(int j=1;j<=m;j++)
     59         if(a[i].x==b[j].x&&a[i].y==b[j].y)
     60           sum++;
     61         else
     62           break;
     63       if(sum==m)
     64         return 1;
     65     }
     66   return 0;
     67 }
     68 bool pan2()
     69 {
     70   for(int i=3;i<=m;i++)
     71     if(jin(a[i]-a[1],a[2]-a[1])!=0)
     72       return 0;
     73   for(int i=1;i<=n;i++)
     74     for(int j=1;j<=n;j++)
     75       {
     76         int sum=0;
     77         for(int k=1;k<=m;k++)
     78           if(cheng(a[i]-b[k],a[j]-b[k])<=0)
     79             sum++;
     80         if(sum==m)
     81           return 0;
     82       }
     83   return 1;
     84 }
     85 int main()
     86 {
     87     n=read();
     88     m=read();
     89     for(int i=1;i<=n;i++)
     90         {
     91             double a1;
     92             scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a1);
     93         }
     94     for(int i=1;i<=m;i++)
     95         {
     96             double a1;
     97             scanf("%lf%lf%lf",&b[i].x,&b[i].y,&a1);
     98         }
     99     if(pan1())
    100       {
    101         printf("1
    ");
    102         return 0; 
    103       }
    104     if(pan2())
    105       {
    106         printf("-1
    ");
    107         return 0;
    108       }
    109     memset(f,127/3,sizeof(f));
    110     for(int i=1;i<=n;i++)
    111       for(int j=1;j<=n;j++)
    112       if(i!=j)
    113        {
    114          data a1=a[j]-a[i];
    115          int kg=1;
    116          for(int k=1;k<=m;k++)
    117            if(jin(a1,b[k]-a[i])<0)
    118              {
    119                kg=0;
    120                break;
    121              }
    122          if(kg)
    123            f[i][j]=kg;
    124        }
    125        for(int k=1;k<=n;k++)
    126      for(int i=1;i<=n;i++)
    127        for(int j=1;j<=n;j++)
    128              f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
    129        for(int i=1;i<=n;i++)
    130          mx=min(mx,f[i][i]);
    131        if(mx==707406378)
    132          mx=-1;
    133        printf("%d
    ",mx);
    134    return 0;
    135 }
    136 
  • 相关阅读:
    堆排序
    伽马分布
    隔壁-贪心
    对刚—约瑟夫环
    站军姿-两圆并集
    单纯的线性筛素数
    3兔子
    2.圆桌游戏
    1.花
    历史
  • 原文地址:https://www.cnblogs.com/xiw5/p/5648689.html
Copyright © 2011-2022 走看看