1006
题意:有n个点,你最多可以添加m条边, 求 G ( wG ) as ∑ni=1∑nj=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;
}