2017 Multi-University Training Contest - Team 5

1006

题意:有n个点,你最多可以添加m条边, 求 G (wG) as ni=1nj=1dist(i,j)的最小值,  其中dis(i, j)代表两点间的最短距离

思路:很显然如果m >= n - 1 整个图可以是联通的,此时菊花图(就是以一个点为中心,然后把剩下的点都连接到这个中心点上)是最优的方案,分两种情况考虑即可,在联通图中多一条边整个图的权值相应的减少2

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 2e5 + 10;
const int INF = 1e9 + 10;
LL n, m;

int main(){
	int t;	scanf("%d", &t);
	while(t--) {
		scanf("%lld%lld", &n, &m);
		if(n == 1) {
			puts("0");
			continue;
		}
		if(n == 2) {
			puts("2");
			continue;
		}
		if(n * (n - 1) <= m * 2) {
			printf("%lld\n", n * (n - 1));
			continue;
		}
		LL ans;
		if(n - 1 >= m) {
			LL x = m + 1;
			LL y = n - (m + 1);
			ans = x * (x - 1) * 2 - 2 * m + y * (y - 1) * n + x * y * n * 2;
		} else {
			ans = (LL)((n) * (n - 1) * 2LL - 2LL * m);
		}
		printf("%lld\n", ans);
 	}
	return 0;
}


1008

题意:n个数的和是m,然后给出n个数2^n个子集和的数量,让你还原这n个数

思路:(首先可以确定0的数量)首先可以确定的一点是,从1到n第一个不为0的Bi,说明i这个数有Bi个,然后我们依次删掉这个i对整个B数组的影响,那么下次从1到n第一个不为0的数i一定有Bi个

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 2e5 + 10;
const int INF = 1e9 + 10;
int n, m;
LL sum[qq];
LL C[60][60];
void Init() {
	C[0][0] = 1;
	for(int i = 1; i <= 50; ++i) {
		C[i][0] = C[i][i] = 1;
		for(int j = 1; j < i; ++j) {
			C[i][j] = C[i - 1][j] + C[i][j - 1];
		} 
	}
}
int A[60];

int main(){
	int t;	scanf("%d", &t);
//	Init();
	while(t--) {
		scanf("%d%d", &n, &m);
		for(int i = 0; i <= m; ++i) {
			scanf("%lld", sum + i);
		}
		int k = 0;
		while((1 << k) != sum[0])	k++;
		for(int i = 1; i <= k; ++i) {
			A[i] = 0;
		}
		for(int i = k + 1; i <= n; ++i) {
			int p = 1;
			while(sum[p] == 0)	++p;
			A[i] = p;
			for(int j = 0; j <= m; ++j) {
				if(sum[j] > 0) {
					sum[j + p] -= sum[j];
				}
			}
		}
		for(int i = 1; i <= n; ++i) {
			printf(i == 1 ? "%d" : " %d", A[i]);
		}
		puts("");
	}
	return 0;
}

1011

签到题

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define mst(a, b)	memset(a, b, sizeof a)
#define REP(i, x, n)	for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 2e5 + 10;
const int INF = 1e9 + 10;
int num[qq];

int main(){
	int t;	scanf("%d", &t);
	while(t--) {
		int n, k;	scanf("%d%d", &n, &k);
		for(int i = 0; i < n; ++i) {
			scanf("%d", num + i);
		}
		sort(num, num + n);
		int cnt = 1;
		for(int i = n - 2; i >= 0; --i) {
			if(num[i + 1] - num[i] <= k)	cnt++;
			else{
				break;
			}	
		}
		printf("%d\n", cnt);
	}
	return 0;
}


你可能感兴趣的:(线上比赛)