2017 Multi-University Training Contest

来源:互联网 发布:淘宝蓝冠和钻石哪个好 编辑:程序博客网 时间:2024/06/06 02:49

1006

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

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

#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <ctime>#include <iostream>#include <algorithm>#include <sstream>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <utility>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 <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <ctime>#include <iostream>#include <algorithm>#include <sstream>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <utility>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 <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <ctime>#include <iostream>#include <algorithm>#include <sstream>#include <string>#include <vector>#include <queue>#include <stack>#include <map>#include <set>#include <utility>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;}