BUPT 网赛测试赛 II B 起重机

这题当时我直接裸搜了,其实应该想到的 15! 肯定要超时啊。。。

不过这题当时LG也做了,他过了,看他代码,用的状态压缩。。

后来看状态压缩的论文,了解了下,今天再看他的代码就很明白了= =。。基本上照抄了一遍囧,改了点小地方。。


位运算的状态压缩,相当于把所有状态都考虑到了,这个题也就2^15个状态,所以时间复杂度比N!小多了,然后枚举一个状态的情况即可。

也就是枚举两个圆,看是否相交,很神奇捏。。2^N*N的时间复杂度。。

给BUPT发邮件了。。这题没加他们题目列表。。。没验证呢。。

不过我觉得是对的哈~~

P.S. BUPT加上题啦~~~嘿嘿


#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define FOR(i,s,t) for(int i=(s); i<(t); i++)
#define BUG puts("here!!!")
#define STOP system("pause")
#define file_r(x) freopen(x, "r", stdin)
#define file_w(x) freopen(x, "w", stdout)

using namespace std;

const int MAX = 20;
struct point {
	int x, y, r;
	void get()
	{
		scanf("%d%d%d", &x, &y, &r);
	}
};
point p[MAX];
long long disp2p(point a,point b)
{
	return (a.x - b.x)*1ll*(a.x - b.x) + (a.y - b.y)*1ll*(a.y - b.y);
}
bool inst(int x, int y)
{
	return disp2p(p[y], p[x]) <= (p[y].r + p[x].r)*1ll*(p[y].r + p[x].r);
}

bool BIN(int i, int n)
{
	FOR(j, 0, n)
		FOR(k, j+1, n)
			if( ( (1<<j) & i ) && ((1<<k) & i ) )
				if( inst(j, k) )  	// 如果相交 
					return false;
	return true;
}
int solve(int n)
{
	int ans, mmax = 0;
	FOR(i, 0, 1<<n)
	{
		ans = 0;
		bool f = BIN(i, n);
		if( f )
			FOR(k, 0, n)
				if( (1<<k) & i )
					ans += p[k].r * p[k].r;
		mmax = max(mmax, ans);
	}
	return mmax;
}

int main()
{
	int n, ncases;

	scanf("%d", &ncases);
	
	while( ncases-- )
	{
		scanf("%d", &n);
		FOR(i, 0, n)
			p[i].get();
		
		int ans = solve(n);
		printf("%d\n", ans);
	}

return 0;
}


你可能感兴趣的:(struct,File,测试,System)