zoukankan      html  css  js  c++  java
  • [NOIp2016提高组]愤怒的小鸟

    题目大意:
      平面直角坐标系的第一象限有n(n<=18)个点,你可以每次给出一个形如y=ax^2+bx的函数把经过这条函数的点消掉,问消掉所有的点至少要多少函数?

    思路:
      枚举每两个点对,可以唯一确定一条函数,再枚举第三个点,判断一下是否会经过这条函数。
      状态压缩一下记录每条函数能消掉那些点。
      然后就是一个简单的状压DP。
      一开始由于把fabs打成了abs,样例都过不去,调了半个下午。
      洛谷上随便A,UOJ上被Extra数据hack掉了,把eps从1e-7改成1e-10就A了。

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<algorithm>
     5 inline int getint() {
     6     register char ch;
     7     while(!isdigit(ch=getchar()));
     8     register int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int N=18;
    13 const double eps=1e-10;
    14 struct Point {
    15     double x,y;
    16 };
    17 Point p[N];
    18 int sit[N*N],s;
    19 int f[1<<N];
    20 inline double pow(const double &x) {
    21     return x*x;
    22 }
    23 int main() {
    24     for(register int T=getint();T;T--) {
    25         const int n=getint();getint();
    26         for(register int i=0;i<n;i++) {
    27             scanf("%lf%lf",&p[i].x,&p[i].y);
    28         }
    29         for(register int i=0;i<n;i++) {
    30             sit[i]=1<<i;
    31         }
    32         s=n;
    33         for(register int i=0;i<n;i++) {
    34             for(register int j=i+1;j<n;j++) {
    35                 const double x1=p[i].x,x2=p[j].x,y1=p[i].y,y2=p[j].y;
    36                 if(pow(x1)*x2==pow(x2)*x1) continue;
    37                 const double a=(x2*y1/x1-y2)/(x1-x2)/x2,b=((pow(x2)*y1/pow(x1)-y2)/(pow(x2)/x1-x2));
    38                 if(a>-eps) continue;
    39                 sit[s]=(1<<i)|(1<<j);
    40                 for(register int k=j+1;k<n;k++) {
    41                     if(fabs(a*pow(p[k].x)+b*p[k].x-p[k].y)<eps) sit[s]|=1<<k;
    42                 }
    43                 s++;
    44             }
    45         }
    46         for(register int i=1;i<(1<<n);i++) {
    47             f[i]=1e9;
    48         }
    49         for(register int i=0;i<(1<<n);i++) {
    50             for(register int j=0;j<s;j++) {
    51                 f[i|sit[j]]=std::min(f[i|sit[j]],f[i]+1);
    52             }
    53         }
    54         printf("%d
    ",f[(1<<n)-1]);
    55     }
    56     return 0;
    57 }
  • 相关阅读:
    字节跳动_玩转客户端训练营
    Mac更换鼠标指针样式_mousecape教程
    能否使用GHDL+GTKWave代替Quartus ii
    关于新家布置的一点小经验——开博第一篇
    Azure直播活动资源转成MP4并下载到本地
    程序员必备的6款工具软件!
    Java 类型的 Hibernate 映射
    Window10下Erlang和RabbitMQ的下载安装
    Tomcat部署项目,JS文件及后台数据显示都是乱码问题解决
    go语言入门及基本算法
  • 原文地址:https://www.cnblogs.com/skylee03/p/7784131.html
Copyright © 2011-2022 走看看