版权声明:博主是菜鸡,但转的时候还是说一声吧 https://blog.csdn.net/qq_37666409/article/details/83187537
题意就是给一群小朋友分糖,每个人的糖数必须刚好满足要求
排序贪心,最后如果有剩的糖但每个人都发了的话,有一个小朋友要凉凉
#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;
}
明显走到后面再往前取更优
每个垃圾必然会被拿回来,这部分的答案是固定的,变的就是取几次
考虑某个垃圾是这次取的当中第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;
}
正解应该是回文树吧……不过数据范围比较暴力,我就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;
}
类似于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;
}