Contestant. Rank 4776. Rating -70 (+30 -100).
A. Parallel Projection
题意
给定一个长方体,在长方体的顶部和底部各取一个点,一只蚂蚁只能在平面上向平行于边的方向移动,求出蚂蚁从一个点移动到另一个点的最短路径。
思路
从四个方向分别模拟一下求最小值即可。
时间复杂度:
对应AC代码
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int t = scanner.nextInt();
while(t -- > 0){
int w = scanner.nextInt(), d = scanner.nextInt(), h = scanner.nextInt();
int a = scanner.nextInt(), b = scanner.nextInt(), f = scanner.nextInt(), g = scanner.nextInt();
int p1 = Math.min(a + f + Math.abs(g - b), b + g + Math.abs(f - a));
a = w - a;
b = d - b;
f = w - f;
g = d - g;
int p2 = Math.min(a + f + Math.abs(g - b), b + g + Math.abs(f - a));
System.out.println(h + Math.min(p1, p2));
}
}
}
还是用蚂蚁理解更加经典((
B. Going to the Cinema
题意
给定数组
注意考虑逆否命题:“我不去电影院,而且只有不到
输出所有不让任何人伤心的安排的总数。
思路
首先,显然我们一定得让
接着,我们遍历剩下按升序排序的
然后,我们遍历后面可以不选上的人,并在选上后判断后者是否必须去。
最后,所有可以不选上的人的个数即为答案,因为若在递增序列里间隔选人,会导致命题不成立。
时间复杂度:
对应AC代码
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int t = scanner.nextInt();
while (t-- > 0) {
int n = scanner.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) a[i] = scanner.nextInt();
Arrays.sort(a);
int c = 0, i = 0, ans = 0;
for(;i<n;i++){
if(a[i] == 0) c ++;
else if(a[i] <= c) c ++;
else break;
}
ans++;
while (i++ < n) {
c++;
if (a[i] <= c) {
ans++;
while (i < n && a[i] <= c) {
i++;
c++;
}
}
}
System.out.println(ans);
}
}
}
云里雾里
C. Equal Frequencies
题意
给定一个字符串
思路
考虑到小写字母只有
如何判断操作数最少呢?对于每个字母
确定段数之后,我们先将字符串中各个字母按照出现次数降序排序,然后从头开始遍历每一个字母,若字母数量过多,那么将多出来的位置留空,如果过少,那么在留空的位置填上缺少的字母。最后将序列输出即可。
时间复杂度:
对应AC代码
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int t = scanner.nextInt();
while (t-- > 0) {
int n = scanner.nextInt();
char[] o = scanner.next().toCharArray();
List<Pair<Integer, List<Integer>>> f = new ArrayList<>();
for(int i=0;i<26;i++) f.add(new Pair<>(i, new ArrayList<>()));
for(int i=0;i<n;i++) f.get(o[i] - 'a').B.add(i);
f.sort(Comparator.comparingInt(o1 -> -o1.B.size()));
int best = 0, cnt = 1, cur;
for(int i=1;i<=26;i++){
if(n % i > 0) continue;
cur = 0;
for(int j=0;j<i;j++) cur += Math.min(n / i, f.get(j).B.size());
if(best < cur){
best = cur;
cnt = i;
}
}
System.out.println(n - best);
List<Integer> extra = new ArrayList<>();
char[] res = new char[n];
for(int i=0;i<cnt;i++){
for(int j=0;j<n/cnt;j++){
if(j < f.get(i).B.size()){
res[f.get(i).B.get(j)] = (char) ('a' + f.get(i).A);
}else{
extra.add(f.get(i).A);
}
}
}
int p = 0;
for(int i=0;i<n;i++){
System.out.printf("%c", res[i] == 0 ? (char) ('a' + extra.get(p ++)) : res[i]);
}
System.out.println();
}
}
//实现cpp里的pair 此处略去
//public static class Pair<A, B>{}
}
没想到暴力直接取段数
D. Many Perfect Squares
题意
给定数组
思路
首先,答案绝对是
那么我们来考虑下如何枚举
显然,
设因数为
继续化简,得到
也就是说,只要括号内的式子是偶数,那么
时间复杂度:
对应AC代码
#include <bits/stdc++.h>
using namespace std;
const int N = 500010;
#define int long long
int a[60];
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t, n;
cin >> t;
while(t --){
cin >> n;
for(int i=0;i<n;i++) cin >> a[i];
int ans = 1;
for(int i=0;i<n-1;i++)
for(int j=i+1;j<n;j++) {
int d = a[j] - a[i], x;
for (int p=1;p<=d/p;p++) {
if(d % p == 0){
if((d / p - p) % 2 == 1 || (d / p + p) % 2 == 1) continue;
x = ((d / p - p) / 2) * ((d / p - p) / 2) - a[i];
if(x < 0) continue;
int cnt = 0;
for(int e=0;e<n;e++){
int s = floor(sqrt(a[e] + x));
if(s * s == a[e] + x) cnt ++;
}
ans = max(ans, cnt);
}
}
}
cout << ans << '\n';
}
}
好一个暴力枚举
- 本文链接 https://floating-ocean.github.io/blog_old/posts/405635716/
- 版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!