比赛入口
C Platforms Jumping
做法:题意是一个人要从左边跳到右边,一次只能跳[1,d]步,中间有几块可以移动的木板,问是否能从左边跳到右边,如果可以,输出一种木板可行方案。只有板子不够的情况是不合法的…合法的话输出一种方案即可,直接贪心模拟,只有板子长度加上所有的可跳跃长度比n小的时候是不满足情况的,其他时候都可以输出结果,在找结果的时候,只需要注意可供选择的。
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int N = 1004;
int a[N], c[N];
int main() {
int n, m, d;
read(n); read(m); read(d);
int sum = 0;
for(int i = 0; i < m; ++i) read(c[i]), sum += c[i];
if(sum + (m+1) * (d-1) < n) puts("NO");
else {
puts("YES");
sum = n - sum;
int mid;
for(int i = 0; i < m; ++i) {
mid = d - 1;
while(mid-->0 && sum-->0) printf("0 ");
while(c[i]--) printf("%d ", i+1);
}
while(sum-->0) printf("0 ");
}
return 0;
}
E Yet Another Division Into Teams
做法:题意是有一些人,每个人都有一定的能力值,每个团队的多样度是指该团队最高能力者和最低能力者能力值之差,要问如何组队(每个队伍必须三个人以上),输出每个人所属的队伍编号。思路是dp…
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int N = 2e5+5;
pii a[N];
pli f[N];
int n, cnt, ans[N];
int main() {
read(n);
for(int i = 1; i <= n; ++i) {
read(a[i].first); a[i].second = i;
}
sort(a+1, a+n+1);
for(int i = 1; i <= n; ++i) {
f[i] = make_pair(1e18, 0);
for(int j = max(0, i - 10); j <= i - 3; ++j) {
f[i] = min(f[i], make_pair(f[j].first+a[i].first-a[j+1].first, j));
}
}
for(int i = n; i; i = f[i].second)
for(int j = (++cnt, f[i].second+1); j <= i; ++j)
ans[a[j].second] = cnt;
printf("%lld %d\n", f[n].first, cnt);
for(int i = 1; i <= n; ++i) {
printf("%d ", ans[i]);
}
return 0;
}
F Equalizing Two Strings
做法:题意是给出两个字符串,要求反转两个字符串中相同长度的字符串,问是否有一种方案能使得两个字符串相等。原来是道结论题,在两个字符串所有字母数量相等的情况下,若满足某个字母数量大于2就存在一种方案,后面貌似是奇偶校验(*)??
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int N = 1e6+6;
int a[N], b[N];
char s[N], t[N];
int main() {
int T; read(T);
int n;
while(T--) {
scanf("%d%s%s", &n, s+1, t+1);
for(int i = 1; i <= 26; ++i) a[i] = b[i] = 0;
LL s1 = 0, s2 = 0;
for(int i = 1; i <= n; ++i) {
++a[s[i]-'a'+1]; ++b[t[i]-'a'+1];
for(int j = s[i]-'a'+1; j <= 26; ++j) s1 += a[j];
for(int j = t[i]-'a'+1; j <= 26; ++j) s2 += b[j];
}
int f = 1;
for(int i = 1; i <= 26; ++i) {
if(a[i] != b[i]) {
f = 0; break;
}
}
if(!f) {
puts("NO"); continue;
}
f = 0;
for(int i = 1; i <= 26; ++i) {
if(a[i] >= 2) {
f = 1; break;
}
}
if(f) {
puts("YES"); continue;
}
(s1 - s2) & 1 ? puts("NO") : puts("YES");
}
return 0;
}