记录编号 357315 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOIP 2016]愤怒的小鸟 最终得分 100
用户昵称 GravatarImone NOI2018Au 是否通过 通过
代码语言 C++ 运行时间 0.068 s
提交时间 2016-12-10 15:47:14 内存使用 4.29 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <algorithm>

#define allset(x) ((1<<x)-1)

using namespace std;

#define EPS 1e-8
inline double abs(double x) {
    return x < 0 ? -x : x;
}

#define eqdouble(x,y) (abs(x-y) <= EPS)
#define lessthan(x,y) (x+EPS<y)
#define throwline(a,b,x) (a*x*x+b*x)
#define pigid(x) (1<<x)

int minV, N, M;
double pigx[18], pigy[18];

struct _set {
	int x;
	int num;
	inline bool operator<(const _set& rhs) const {
		return num > rhs.num;
	}
} sets[400];

int Nset;

void solve(double &a, double &b, double x1, double y1, double x2, double y2) {
    double x12 = x1*x1, x22 = x2*x2, 
        kc0 = y1+y2, ka0 = x12+x22, kb0 = x1+x2,
        kc1 = y1-y2, ka1 = x12-x22, kb1 = x1-x2,
        kb1divkb0;
    if(kb0 == 0) return;
    kb1divkb0 = kb1 / kb0;
    if(ka0*kb1divkb0-ka1 == 0) return;
    a = (kc0*kb1divkb0-kc1)/(ka0*kb1divkb0-ka1);
    b = (kc0-ka0*a)/kb0;
}

int queue[262144], qH, qT, dep[262144], left[262144];
int vis[262144], visid = 0;

int main() {
    freopen("angrybirds.in", "rt", stdin);
    freopen("angrybirds.out", "wt", stdout);

    int i,T,k,t,num;
    double a,b;
    
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d", &N, &M);
        for(i=0;i<N;i++) {
            scanf("%lf%lf", &pigx[i], &pigy[i]);
        }

        //pre-process
        Nset = 0;
        visid++; //clear vis
        for(i=0;i<N;i++) {
            for(k=i+1;k<N;k++) {
                a=0; solve(a,b,pigx[i],pigy[i],pigx[k],pigy[k]);
                if(lessthan(a,0)) {
                    sets[Nset].x = pigid(i) | pigid(k);
                    num = 2;
                    for(t=0;t<N;t++) {
                        if(t!=i && t!=k && eqdouble( throwline(a,b,pigx[t]), pigy[t] )) {
                            sets[Nset].x |= pigid(t); num++;
                        }
                    }
                    if(vis[sets[Nset].x] != visid) {
                    	vis[sets[Nset].x] = visid;
                    	sets[Nset].num = num;
                    	Nset++;
					}
                }
            }
        }

		sort(sets, sets+Nset);

        //node sorting
        visid++; //clear vis

        qH = 0; qT = 1;
        queue[0] = allset(N);
        dep[0] = 0;
        left[0] = N;
        minV = N;

        int U, cdep, cleft;
        while(qH < qT) {
        	U = queue[qH]; cdep = dep[qH]; cleft = left[qH]; qH++;

        	if(U == 0) {
        		minV = cdep;
        		break;
			}
			if(cleft+cdep < minV) {
				minV = cleft+cdep;
			}
        	for(i=0;i<Nset;i++) {
        		t = U & (~sets[i].x);
        		if(vis[t] != visid) {
        			vis[t] = visid;
        			
        			num = 0;
        			for(k=0;k<N;k++) {
        				if(t & pigid(k)) num++;
					}
        			queue[qT] = t;
        			dep[qT] = cdep+1;
        			left[qT] = num;
        			qT++;
				}
			}
		}

        printf("%d\n", minV);
    }
}