Educational Codeforces Round 102 (Rated for Div. 2)
A. Replacing Elements
#include <bits/stdc++.h>
using namespace std;
const int N = 100 + 20;
int n, d, a[N];
int main()
{
// freopen("A.in", "r", stdin);
int __;
scanf("%d", &__);
while(__ -- )
{
scanf("%d%d", &n, &d);
for(int i = 1; i <= n; ++ i) scanf("%d", &a[i]);
sort(a + 1, a + n + 1);
if(a[n] <= d) puts("YES");
else if(a[1] + a[2] <= d) puts("YES");
else puts("NO");
}
return 0;
}
B. String LCM
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
int n;
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int main()
{
// freopen("B.in", "r", stdin);
IOS;
int __;
cin >> __;
while(__ -- )
{
string a, b;
cin >> a >> b;
int len = gcd(a.size(), b.size());
string aa, bb;
for(int i = 0; i < (int)b.size() / len; ++ i) aa += a;
for(int i = 0; i < (int)a.size() / len; ++ i) bb += b;
if(aa == bb) cout << aa << endl;
else cout << "-1" << endl;
}
return 0;
}
C. No More Inversions
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 20;
int n, k;
int a[N];
int main()
{
// freopen("C.in", "r", stdin);
int __;
scanf("%d", &__);
while(__ -- )
{
scanf("%d%d", &n, &k);
for(int i = 1; i < 2 * k - n; ++ i) printf("%d ", i);
for(int i = k; i >= 2 * k - n; -- i) printf("%d ", i);
puts("");
}
return 0;
}
D. Program
维护一个前缀最大值最小值和一个后缀最大值最小值即可
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 20;
int n, m;
int pre_max[N], pre_min[N];
int post_max[N], post_min[N];
int val[N];
char s[N];
int main()
{
// freopen("D.in", "r", stdin);
int __;
scanf("%d", &__);
while(__ -- )
{
scanf("%d%d", &n, &m);
scanf("%s", s + 1);
for(int i = 1; i <= n; ++ i)
val[i] = val[i - 1] + (s[i] == '+' ? 1 : -1);
pre_max[1] = pre_min[1] = val[1];
for(int i = 2; i <= n; ++ i)
{
pre_max[i] = max(pre_max[i - 1], val[i]);
pre_min[i] = min(pre_min[i - 1], val[i]);
}
post_min[n] = post_max[n] = val[n];
for(int i = n - 1; i >= 1; -- i)
{
post_max[i] = max(post_max[i + 1], val[i]);
post_min[i] = min(post_min[i + 1], val[i]);
}
for(int i = 1; i <= m; ++ i)
{
int l, r;
scanf("%d%d", &l, &r);
int maxres = 0, minres = 0;
if(l > 1)
{
maxres = max(maxres, pre_max[l - 1]);
minres = min(minres, pre_min[l - 1]);
}
if(r < n)
{
int tmp = val[r] - val[l - 1];
maxres = max(maxres, post_max[r + 1] - tmp);
minres = min(minres, post_min[r + 1] - tmp);
}
printf("%d\n", maxres + abs(minres) + 1);
}
}
return 0;
}
E. Minimum Path
找到一条路径,使得 路径长度 - 最长边 + 最短边 的值最大.
建一个4层的分层图,1向2,3向4建(x, y, 0), 表示该边是最长边,1向3,2向4建(x, y, 2 * z),表示该边是最短边,1向4建(x, y, z)表示该边既是最长边也是最短边.
然后求最短路即可.
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL INF = 1e18;
const int N = 2e5 + 20;
struct Edge
{
int to, nxt, w;
}line[N * 20];
int fist[N * 4], idx;
int n, m;
void add(int x, int y, int z)
{
line[idx] = (Edge){y, fist[x], z};
fist[x] = idx ++;
}
void addedge(int x, int y, int z)
{
add(x, y, z); add(x + n, y + n, z);
add(x + 2 * n, y + 2 * n, z); add(x + 3 * n, y + 3 * n, z);
add(x, y + n, 0); add(x + 2 * n, y + 3 * n, 0);
add(x, y + 2 * n, 2 * z); add(x + n, y + 3 * n, 2 * z);
add(x, y + 3 * n, z);
}
bool st[N * 4];
LL dis[N * 4];
struct zt
{
int x;
LL d;
};
bool operator < (zt a, zt b)
{
return a.d > b.d;
}
void heap_dijkstra()
{
priority_queue<zt> q;
for(int i = 1; i <= 4 * n; ++ i) dis[i] = INF;
dis[1] = 0;
q.push((zt){1, 0});
while(!q.empty())
{
zt u = q.top(); q.pop();
if(st[u.x]) continue;
st[u.x] = 1;
for(int i = fist[u.x]; i != -1; i = line[i].nxt)
{
int v = line[i].to;
if(dis[v] > dis[u.x] + line[i].w)
{
dis[v] = dis[u.x] + line[i].w;
q.push((zt){v, dis[v]});
}
}
}
}
int main()
{
// freopen("E.in", "r", stdin);
memset(fist, -1, sizeof fist);
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; ++ i)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
addedge(a, b, c);
addedge(b, a, c);
}
heap_dijkstra();
for(int i = 2; i <= n; ++ i)
printf("%lld ", dis[i + 3 * n]);
puts("");
return 0;
}
另一种写法,可以写成dis[i][0/1][0/1]表示当前状态,用状态转移的形式选择当前边是否是最长边或最短边.
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL INF = 1e18;
const int N = 2e5 + 20;
int n, m;
int fist[N], idx;
struct Edge
{
int to, nxt, w;
}line[N * 2];
void add(int x, int y, int z)
{
line[idx] = (Edge){y, fist[x], z};
fist[x] = idx ++;
}
bool st[N][2][2];
LL dis[N][2][2];
struct zt
{
int x, t1, t2;
LL d;
};
bool operator < (zt a, zt b)
{
return a.d > b.d;
}
void heap_dijkstra()
{
priority_queue<zt> q;
for(int i = 1; i <= n; ++ i)
for(int j = 0; j <= 1; ++ j)
for(int k = 0; k <= 1; ++ k)
dis[i][j][k] = INF;
dis[1][0][0] = 0;
q.push((zt){1, 0, 0, 0});
while(!q.empty())
{
zt u = q.top(); q.pop();
if(st[u.x][u.t1][u.t2]) continue;
st[u.x][u.t1][u.t2] = 1;
for(int i = fist[u.x]; i != -1; i = line[i].nxt)
{
int v = line[i].to;
if(dis[v][u.t1][u.t2] > dis[u.x][u.t1][u.t2] + line[i].w)
{
dis[v][u.t1][u.t2] = dis[u.x][u.t1][u.t2] + line[i].w;
q.push((zt){v, u.t1, u.t2, dis[v][u.t1][u.t2]});
}
if(!u.t1 && dis[v][1][u.t2] > dis[u.x][u.t1][u.t2] + 0)
{
dis[v][1][u.t2] = dis[u.x][u.t1][u.t2];
q.push((zt){v, 1, u.t2, dis[v][1][u.t2]});
}
if(!u.t2 && dis[v][u.t1][1] > dis[u.x][u.t1][u.t2] + 2 * line[i].w)
{
dis[v][u.t1][1] = dis[u.x][u.t1][u.t2] + 2 * line[i].w;
q.push((zt){v, u.t1, 1, dis[v][u.t1][1]});
}
if(!u.t1 && !u.t2 && dis[v][1][1] > dis[u.x][u.t1][u.t2] + line[i].w)
{
dis[v][1][1] = dis[u.x][u.t1][u.t2] + line[i].w;
q.push((zt){v, 1, 1, dis[v][1][1]});
}
}
}
}
int main()
{
// freopen("E.in", "r", stdin);
memset(fist, -1, sizeof fist);
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; ++ i)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c);
add(b, a, c);
}
heap_dijkstra();
for(int i = 2; i <= n; ++ i)
printf("%lld ", dis[i][1][1]);
puts("");
return 0;
}
2021.1.19