Codeforces Round #597 (Div. 2)
# | 题目 | 分数 | 是否AC |
---|---|---|---|
A | Good ol’ Numbers Coloring | 1000 | ✅ |
B | Restricted RPS | 1200 | ✅ |
C | Constanze’s Machine | 1400 | ✅ |
D | Shichikuji and Power Grid | 1900 | ✅ |
E | Hyakugoku and Ladders | 2300 | ❌ |
F | Daniel and Spring Cleaning | 2300 | ❌ |
A. 题目
题目类型 数论
题意
分析
时间复杂度
O ( log n ) O( \log n ) O(logn)
代码
public static void solve() throws IOException {
int a = nextInt();
int b = nextInt();
if (gcd(a, b) == 1) pw.println("Finite");
else pw.println("Infinite");
}
public static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
B. 题目
题目类型 贪心
题意
分析
尽量赢。遍历 Bob 的出拳序列,如果 Alice 存在可以赢得拳就先出,如果没有就先空着。最后统计赢得个数是否满足题意,如果满足就把空着得位置用没出得拳补上就行。
时间复杂度
O ( n ) O( n ) O(n)
代码
public static void solve() throws IOException {
int n = nextInt();
int[] a = new int[130];
a['R'] = nextInt();
a['P'] = nextInt();
a['S'] = nextInt();
char[] s = next().toCharArray();
char[] ss = new char[n];
System.arraycopy(s, 0, ss, 0, n);
for (int i = 0; i < n; i++) {
switch (s[i]) {
case 'R': if (a['P']-- > 0) s[i] = '-'; break;
case 'P': if (a['S']-- > 0) s[i] = '-'; break;
case 'S': if (a['R']-- > 0) s[i] = '-'; break;
}
}
int cnt = 0;
for (char i : s) if (i == '-') cnt++;
if (cnt >= (int) Math.ceil((double) n / 2)) {
pw.println("YES");
for (int i = 0; i < n; i++) {
if (s[i] == '-') {
switch (ss[i]) {
case 'R': pw.print('P'); break;
case 'P': pw.print('S'); break;
case 'S': pw.print('R'); break;
}
} else {
if (a['R']-- > 0) pw.print('R');
else if (a['P']-- > 0) pw.print('P');
else if (a['S']-- > 0) pw.print('S');
}
}
pw.println();
} else {
pw.println("NO");
}
}
C. 题目
题目类型 思维 组合数 动态规划
题意
分析
对于相连 n n n 或 u u u 不同个数贡献的不同字符串的个数进行打表发现是斐波那契额数列。那么就可以统计出每段相连 n n n 或 u u u 的贡献然后用乘法原理计算结果。
时间复杂度
O ( n ) O(n) O(n)
代码
static final int Mod = 1000000007;
public static void solve() throws IOException {
char[] s = next().toCharArray();
int[] TB = new int[s.length + 1];
makeTB(TB, 1000000007);
long ans = 1;
for (int i = 0; i < s.length; i++) {
if (s[i] == 'w' || s[i] == 'm') {
pw.println(0);
return ;
}
if (s[i] == 'n') {
int j = i;
while (j + 1 < s.length && s[j + 1] == 'n') j++;
ans = (ans * TB[j - i + 1]) % Mod;
i = j;
}
if (s[i] == 'u') {
int j = i;
while (j + 1 < s.length && s[j + 1] == 'u') j++;
ans = (ans * TB[j - i + 1]) % Mod;
i = j;
}
}
pw.println(ans);
}
public static void makeTB(int[] TB, int Mod) {
TB[0] = 1; TB[1] = 1;
for (int i = 2; i < TB.length; i++)
TB[i] = (TB[i - 1] + TB[i - 2]) % Mod;
}
打表代码
public static void solve() throws IOException {
StringBuilder s = new StringBuilder();
for (int i = 0; i < 10; i++) {
TreeSet<StringBuilder> set = new TreeSet<>();
dfs(s, 0, set);
set.add(s);
pw.println("n : " + i + " cnt :" + set.size());
s.append('n');
}
}
public static void dfs(StringBuilder s, int step, TreeSet<StringBuilder> set) {
if (step + 1 >= s.length()) return ;
StringBuilder s1 = new StringBuilder(s);
StringBuilder s2 = new StringBuilder(s);
if (s1.charAt(step) == 'n' && s1.charAt(step + 1) == 'n') {
s1.replace(step, step + 2, "m");
set.add(s1);
dfs(s1, step + 1, set);
}
set.add(s2);
dfs(s2, step + 1, set);
}
D. 题目
题目类型
题意
分析
时间复杂度
O ( n 2 log n 2 ) O( n^2 \log n^2 ) O(n2logn2)
代码
static Edge[] edge;
static int idx;
static int[] ans1;
static int ans1Idx;
static Edge[] ans2;
static int ans2Idx;
public static void solve() throws IOException {
int n = nextInt();
init(n);
Vertex[] v = new Vertex[n + 1];
for (int i = 1; i <= n; i++) v[i] = new Vertex(nextInt(), nextInt());
int[] c = new int[n + 1];
for (int i = 1; i <= n; i++) c[i] = nextInt();
int[] k = new int[n + 1];
for (int i = 1; i <= n; i++) k[i] = nextInt();
for (int i = 1; i <= n; i++) edge[idx++] = new Edge(0, i, c[i]);
for (int i = 1; i <= n; i++)
for (int j = i + 1; j <= n; j++)
edge[idx++] = new Edge(i, j, getCost(v, k, i, j));
long ans = kruskal(n);
pw.println(ans);
pw.println(ans1Idx);
for (int i = 0; i < ans1Idx; i++) pw.print(ans1[i] + " ");
pw.println();
pw.println(ans2Idx);
for (int i = 0; i < ans2Idx; i++) pw.println(ans2[i].from + " " + ans2[i].to);
}
public static long kruskal(int n) {
int[] fa = new int[n + 1];
int[] rank = new int[n + 1];
for (int i = 0; i < fa.length; i++) {
fa[i] = i;
rank[i] = 1;
}
Arrays.sort(edge, 0, idx, new Comparator<Edge>() {
@Override
public int compare(Edge o1, Edge o2) {
return Long.compare(o1.cost, o2.cost);
}
});
long re = 0;
int cnt = 0;
for (int i = 0; i < idx; i++) {
Edge e = edge[i];
if (!same(fa, e.from, e.to)) {
unite(fa, rank, e.from, e.to);
re += e.cost;
cnt++;
if (e.from == 0) {
ans1[ans1Idx++] = e.to;
} else {
ans2[ans2Idx++] = e;
}
}
if (cnt == n) break;
}
return re;
}
public static int find(int[] fa, int x) {
return fa[x] == x ? x : (fa[x] = find(fa, fa[x]));
}
public static void unite(int[] fa, int[] rank, int x, int y) {
x = find(fa, x);
y = find(fa, y);
if (x == y) return ;
if (rank[x] < rank[y]) fa[x] = y;
else {
fa[y] = x;
if (rank[x] == rank[y]) rank[x]++;
}
}
public static boolean same(int[] fa, int x, int y) {
return find(fa, x) == find(fa, y);
}
public static void init(int n) {
edge = new Edge[n * n + n];
idx = 0;
ans1 = new int[n + 1];
ans1Idx = 0;
ans2 = new Edge[n + 1];
ans2Idx = 0;
}
public static long getCost(Vertex[] v, int[] k, int i, int j) {
return (long) (k[i] + k[j]) * (Math.abs(v[i].x - v[j].x) + Math.abs(v[i].y - v[j].y));
}
/*******************************************************************************************************************************/
static class Edge {
int from, to;
long cost;
public Edge(int from, int to, long cost) {
this.from = from;
this.to = to;
this.cost = cost;
}
}
static class Vertex {
int x, y;
public Vertex(int x, int y) {
this.x = x;
this.y = y;
}
}
E. 题目
题目类型
题意
分析
时间复杂度
O ( ) O( ) O()
代码
这里粘贴代码
F. 题目
题目类型
题意
分析
时间复杂度
O ( ) O( ) O()
代码
这里粘贴代码