• Luogu P1378 油滴扩展


    solution

    这是一道很值得反思的题目
    首先关于double的基本用法就非常不熟悉

    1. int + 0.0 = double int转化成double的方法
    2. printf 0.lf% 直接四舍五入输出int
      关于题目其实并不是个很难的题目
      关键就是搜索计算状态
      就是比较得出r的过程 //特判一个r不用出来的答案直接当0计算
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define INF 2147483647
    #define pi 3.1415926535
    int N,L,R;
    int sx,sy,ex,ey;
    bool vis[10];
    double b[10],maxV=0.0;
    struct Node{
      int x,y;
    }Dot[10];
    double calR(double mx,double my,int i){
      double tx=min(abs(mx-sx+0.0),abs(mx-ex+0.0));
      double ty=min(abs(my-sy+0.0),abs(my-ey+0.0));
      double r=min(tx,ty);
      for(int k=1;k<=N;k++){
        if(i!=k&&vis[k]){
          double Dist=sqrt((mx-Dot[k].x)*(mx-Dot[k].x)+(my-Dot[k].y)*(my-Dot[k].y));
          if(Dist-b[k]<=0)return 0; // 特判一个已经在里面的答案直接return0;
          r=min(r,Dist-b[k]); // 不断优化当前r的答案
        }
      }
      return r; // 返回当前情况的最优r
    }
    void dfs(double sum,int step){//搜索的本质就是穷竭枚举,所以不用考虑什么排序之类的东西
      if(step==N){
        if(sum>maxV)
          maxV=sum;
        return;
      }
      for(int i=1;i<=N;i++){
        if(!vis[i]){
          vis[i]=1;
          b[i]=calR(Dot[i].x+0.0,Dot[i].y+0.0,i);//用b[i]记录对于i点当前的最有r答案
          dfs(sum+pi*b[i]*b[i],step+1);
          vis[i]=0;
          b[i]=0.0;
        }
      }
    }
    int main(){
      cin>>N;
      cin>>sx>>sy>>ex>>ey;
      L=abs(ex-sx),R=abs(ey-sy);
      for(int i=1;i<=N;i++) cin>>Dot[i].x>>Dot[i].y;
      dfs(0,0);
      double Ans=L*R+0.0-maxV;
      printf("%.0lf
    ",Ans);
      return 0;
      
    }
    
    
  • 相关阅读:
    易语言常用源码
    ci的数据库地址
    格式化输出php数组
    mysql插入表情问题
    线程、进程与协程2
    线程、进程与协程
    if __name=='__main__"的作用
    动态导入模块
    面向对象补充之方法
    getpass模块
  • 原文地址:https://www.cnblogs.com/KingBenQi/p/12301472.html
Copyright © 2020-2023  润新知