杂题练习10.12

版权声明:博主是菜鸡,但转的时候还是说一声吧 https://blog.csdn.net/qq_37666409/article/details/83187537

AtCoder 4375

题意就是给一群小朋友分糖,每个人的糖数必须刚好满足要求

排序贪心,最后如果有剩的糖但每个人都发了的话,有一个小朋友要凉凉

#include <bits/stdc++.h>
#define LL long long
#define db double
using namespace std;
 
const int MAXN = 2002;
const int MAXE = 400400;
const int INF = 0x3f3f3f3f;
 
template<typename T> inline void CheckMax(T &A, T B) {
	A < B ? A = B : A;
}
 
template<typename T> inline void CheckMin(T &A, T B) {
	A > B ? A = B : A;
}
 
template <typename T> inline void read(T &x) {
    int c = getchar();
    bool f = false;
    for (x = 0; !isdigit(c); c = getchar()) {
        if (c == '-') {
            f = true;
        }
    }
    for (; isdigit(c); c = getchar()) {
        x = x * 10 + c - '0';
    }
    if (f) {
        x = -x;
    }
}

int n, X, a[200];

signed main() {
	read(n), read(X);
	for(int i = 1; i <= n; i++) read(a[i]);
	sort(a + 1, a + n + 1);
	int ans = 0;
	for(int i = 1; i <= n; i++) {
		if(X >= a[i]) X -= a[i], ans++;
	}
	if(ans == n && X) ans--;
	printf("%d\n", ans);
	return 0;
}

AtCoder 4376

明显走到后面再往前取更优

每个垃圾必然会被拿回来,这部分的答案是固定的,变的就是取几次

考虑某个垃圾是这次取的当中第1, 2, 3, 4……个被取的,计算其贡献,去的贡献就是坐标x,回的贡献就是(i + 1)^2 * x,i表示这是第几个取的,将其差分,其系数为5, 5, 7, 9……

连续的一段的系数是一样的(即这一段分别是第1, 2, 3....i次取的第k个),长度和i有关

贪心即可

#include <bits/stdc++.h>
#define LL long long
#define db double
using namespace std;
 
const int MAXN = 200200;
const int MAXE = 400400;
const int INF = 0x3f3f3f3f;
 
template<typename T> inline void CheckMax(T &A, T B) {
	A < B ? A = B : A;
}
 
template<typename T> inline void CheckMin(T &A, T B) {
	A > B ? A = B : A;
}
 
template <typename T> inline void read(T &x) {
    int c = getchar();
    bool f = false;
    for (x = 0; !isdigit(c); c = getchar()) {
        if (c == '-') {
            f = true;
        }
    }
    for (; isdigit(c); c = getchar()) {
        x = x * 10 + c - '0';
    }
    if (f) {
        x = -x;
    }
}

int X, a[MAXN], n;
LL sum[MAXN];

LL diff(int l, int r) {
	return sum[r] - sum[l - 1];
}

signed main() {
	read(n), read(X);
	for(int i = 1; i <= n; i++) read(a[i]);
	for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] + (LL) a[i];
	LL ans = (1LL << 61);
	for(int i = 1; i <= n; i++) {
		LL res = (LL)i * X;
		for(int j = n, k = 1; j && res < ans; k++) {
			int pos = max(j - i + 1, 1);
			res += diff(pos, j) * (LL)(k == 1 ? 5 : (k << 1 | 1));
			j = pos - 1;
		}
		ans = min(ans, res);
	}
	printf("%lld\n", ans + (LL) n * (LL) X);
	return 0;
}

Gym101806Q

正解应该是回文树吧……不过数据范围比较暴力,我就manacher暴力跑过去了

#include <bits/stdc++.h>
#define LL long long
#define db double
using namespace std;
 
const int MAXN = 200200;
const int MAXE = 400400;
const int INF = 0x3f3f3f3f;
 
template<typename T> inline void CheckMax(T &A, T B) {
	A < B ? A = B : A;
}
 
template<typename T> inline void CheckMin(T &A, T B) {
	A > B ? A = B : A;
}
 
template <typename T> inline void read(T &x) {
    int c = getchar();
    bool f = false;
    for (x = 0; !isdigit(c); c = getchar()) {
        if (c == '-') {
            f = true;
        }
    }
    for (; isdigit(c); c = getchar()) {
        x = x * 10 + c - '0';
    }
    if (f) {
        x = -x;
    }
}

char s1[MAXN], s2[MAXN];
int len1, len2;
int p[MAXN]; 
void init() {
    s2[0] = '$';
    s2[1] = '#';
    for(int i = 0; i < len1; i++) {
        s2[2 * i + 2] = s1[i];
        s2[2 * i + 3] = '#';
    }
    len2 = len1 * 2 + 2;
    s2[len2] = '&';
}

void manacher() {
    int id = 0, mx = 0;
    for(int i = 1; i < len2; i++) {
        if(mx > i) p[i] = min(p[2 * id - i], mx - i);
        else p[i] = 1;
        while(s2[i + p[i]] == s2[i - p[i]]) p[i]++;
        if(i + p[i] > mx) {
            mx = i + p[i];
            id = i;
        }
    }
}

int Q;
char opt[MAXN];

int calc() {
	int ans = 0;
	for(int i = 1; i < len2; i++) {
		ans += (p[i] >> 1);
	}
	return ans;
}

signed main() {
	read(Q);
	scanf("%s", opt);
	for(int i = 0; i < Q; i++) {
		if(opt[i] == '-') {
			len1--;
		}
		else {
			s1[len1++] = opt[i];
		}
		init();
		manacher();
		printf("%d%c", calc(), i == Q - 1 ? '\n' : ' ');
	}
	return 0;
}

UVa11392

类似于111111....或者33333.....这种数对一个数取模是有循环节的,假如是mod n,循环节长度必然不超过n

用给出的n中的2和5的个数决定0的个数,暴力枚举3的个数

#include <bits/stdc++.h>
#define LL long long
#define db double
using namespace std;
 
const int MAXN = 2002;
const int MAXE = 400400;
const int INF = 0x3f3f3f3f;
 
template<typename T> inline void CheckMax(T &A, T B) {
	A < B ? A = B : A;
}
 
template<typename T> inline void CheckMin(T &A, T B) {
	A > B ? A = B : A;
}
 
template <typename T> inline void read(T &x) {
    int c = getchar();
    bool f = false;
    for (x = 0; !isdigit(c); c = getchar()) {
        if (c == '-') {
            f = true;
        }
    }
    for (; isdigit(c); c = getchar()) {
        x = x * 10 + c - '0';
    }
    if (f) {
        x = -x;
    }
}

int n;

signed main() {
	while(scanf("%d", &n) == 1) {
		int a, b, c;
		a = b = 0;
		while(n % 5 == 0) n /= 5, a++;
		while(n % 2 == 0) n >>= 1, b++;
		a = max(a, b);
		int k = 3;
		for(c = 1; k % n; k = k % n * 10 + 3, c++);
		printf("%d %d %d\n", a + c, c, a);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37666409/article/details/83187537