Noip2016Day2T3 Angry Birds

Topic Link

problem

Of n points in a plane, each one can be determined through the origin and is open upwardly parabola, the parabola all these points are omitted. Q. requires a minimum of a few can delete to delete all of the points.

solution

n is relatively small, direct-like press down. As it has been determined to be through the origin. So every two points can determine a parabola. Pretreatment all parabolic and can be deleted for each point of the parabola.

Then the memory of the search, select enumerate each parabola. Transfer can be.

Note Accuracy!

The method of determining the parabola on the solution to the method of linear equations group. details as follows:

Coefficient of the quadratic parabola is \ (A \) , a coefficient of \ (B \) , the coordinates of two points are \ ((x_i, y_i), (x_j, y_j) \) .

\(k_1=x_i^2,k_2=x_i,k_3=y_i,k_4=x_j^2,k_5=x_j,k_6=y_j\)

Then is the solution of equations

\[\left\{ \begin{aligned} k_1a+k_2b=k_3& &(1)\\ k_4a+k_5b=k_6& &(2) \end{aligned} \right. \]

By the \ ((1) \) to give \ (B = \ {K_3 FRAC-k_1a K_2} {} \) , substituting back \ ((2) \) to give \ (a = \ frac {k_2k_6 -k_3k_5} {k_2k_4- k_1k_5} \)

code

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
typedef long long ll;
const double eps = 1e-9;
ll read() {
    ll x = 0,f = 1;char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x * f;
}
int tot;
bool calc(double a,double b,double x,double y) {
    return fabs(a * x * x + b * x - y) <= eps;
}
double x[20],y[20],a[400],b[400];
int sol[400];
int n,m,f[1 << 20];
int dfs(int now) {
    if(!now) return f[now] = 0;
    if(f[now] != -1) return f[now];
    int ret = 100000;
    for(int i = 1;i <= tot;++i) {
        int t = now & sol[i];
        if(t != now) ret = min(ret,dfs(t) + 1);
    }
    return f[now] = ret;
}
int main() {
    int T = read();
    while(T--) {
        tot = 0;
        memset(f,-1,sizeof(f));
        n = read(),m = read();
        for(int i = 1;i <= n;++i) scanf("%lf%lf",&x[i],&y[i]);
        
        for(int i = 1;i <= n;++i) {
            for(int j = i + 1;j <= n;++j) {
                if(fabs(x[i] - x[j]) <= eps) continue;
                ++tot;
                double k1 = x[i] * x[i],k2 = x[i],k3 = y[i],k4 = x[j] * x[j],k5 = x[j],k6 = y[j];
                a[tot] = ((k6 * k2 - k3 * k5)) / ((k4 * k2 - k1 * k5));
                b[tot] = (k3 - k1 * a[tot]) / k2;
                if(a[tot] >= 0) --tot;
            }
        }
        
        
        for(int i = 1;i <= tot;++i) {
            
            sol[i] = (1 << n) - 1;
            
            for(int j = 1;j <= n;++j) 
                if(calc(a[i],b[i],x[j],y[j])) sol[i] ^= (1 << (j - 1)); 
        }
        
        for(int i = 1;i <= n;++i) {
            ++tot;
            sol[tot] = ((1 << n) - 1) ^ (1 << (i - 1));
        }
        
        printf("%d\n",dfs((1 << n) - 1));
    }
    
    return 0;
}

Guess you like

Origin www.cnblogs.com/wxyww/p/11628340.html