Tak and Hotels (ABC Edit)
前k晚花费x,k+1晚以后花费y
AC代码:
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) {
InputStream inputStream = System.in;
OutputStream outputStream = System.out;
InputReader in = new InputReader(inputStream);
PrintWriter out = new PrintWriter(outputStream);
Solve Work = new Solve();
int T = 1;
// int T = Integer.parseInt(in.next());
for (int i = 1; i <= T; i++) {
Work.main(i, in, out);
}
out.close();
}
static class Solve {
public void main(int testNumber, InputReader in, PrintWriter out) {
int n = in.nextInt(), k = in.nextInt(), x = in.nextInt(), y = in.nextInt();
int ans = 0;
if (n >= k) {
ans = k * x + (n - k) * y;
} else {
ans = n * x;
}
out.println(ans);
}
}
//IO
static class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
}
}
Beautiful Strings
字符串中出现的字符,每种字符的个数为偶数
AC代码:
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) {
InputStream inputStream = System.in;
OutputStream outputStream = System.out;
InputReader in = new InputReader(inputStream);
PrintWriter out = new PrintWriter(outputStream);
Solve Work = new Solve();
int T = 1;
// int T = Integer.parseInt(in.next());
for (int i = 1; i <= T; i++) {
Work.main(i, in, out);
}
out.close();
}
static class Solve {
public void main(int testNumber, InputReader in, PrintWriter out) {
String s = in.next();
int len = s.length();
int[] cnt = new int[26];
for (int i = 0; i < len; i++) {
cnt[s.charAt(i) - 'a']++;
}
boolean ok = true;
for (int i = 0; i < 26; i++) {
if (cnt[i] % 2 == 1) {
ok = false;
break;
}
}
if (ok) {
out.println("Yes");
} else {
out.println("No");
}
}
}
//IO
static class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
}
}
Tak and Cards
题意是在序列中选择任意个数使得他们的平均数为A的方案数
DP,考虑到尽量不要使用浮点数,那么就将A扩大对应的倍数即可,显然是个01背包问题,这里直接用滚动数组优化后的dp,状态就是前i个里面选j个和为k,其中j<=i,k<= ,因为滚动数组中存的是上一轮状态的解,所以这里要从大到小枚举,可得转移方程dp[j][k]=dp[j][k]+dp[j-1][k-x[i]]
AC代码:
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) {
InputStream inputStream = System.in;
OutputStream outputStream = System.out;
InputReader in = new InputReader(inputStream);
PrintWriter out = new PrintWriter(outputStream);
Solve Work = new Solve();
int T = 1;
// int T = Integer.parseInt(in.next());
for (int i = 1; i <= T; i++) {
Work.main(i, in, out);
}
out.close();
}
static class Solve {
public void main(int testNumber, InputReader in, PrintWriter out) {
int n = in.nextInt(), A = in.nextInt();
int[] x = new int[n + 1];
for (int i = 1; i <= n; i++) {
x[i] = in.nextInt();
}
long[][] dp = new long[(n + 1)][500 * 500 + 10];
dp[0][0] = 1;
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += x[i];
for (int j = i; j >= 1; j--) {
for (int k = sum; k >= x[i]; k--) {
dp[j][k] = dp[j][k] + dp[j - 1][k - x[i]];
}
}
}
long ans = 0;
for (int i = 1; i <= n; i++) {
ans = ans + dp[i][i * A];
}
out.println(ans);
}
}
//IO
static class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
}
}
Digit Sum
求最小的b进制,使得在b进制下的n的各位之和为s,如果不存在输出-1
可以观察到当n==s的时候答案为n+1,当n<s时答案为-1
最后讨论当n>s时
当b的最高幂次大于等于2的时候,
进而
所以可以暴力枚举b从[2,],判断是否有满足条件的最小的b
当b的最高幂次小于2的时候,
联立上述两式可得
有了上述公式,可以从大到小枚举,这样相当于从小到大在枚举b,从而可以找到最小的符合条件的b,由于前面已经筛过了b从[2,],这里只需要枚举b从(,n-s],并且可以得到,所以只需要枚举的部分即可
AC代码:
import java.util.*;
import java.io.*;
import java.math.*;
public class Main {
public static void main(String[] args) {
InputStream inputStream = System.in;
OutputStream outputStream = System.out;
InputReader in = new InputReader(inputStream);
PrintWriter out = new PrintWriter(outputStream);
Solve Work = new Solve();
int T = 1;
// int T = Integer.parseInt(in.next());
for (int i = 1; i <= T; i++) {
Work.main(i, in, out);
}
out.close();
}
static class Solve {
public void main(int testNumber, InputReader in, PrintWriter out) {
long n = in.nextLong(), s = in.nextLong();
long z = (long)Math.sqrt(1.0 * n) + 1;
for (long i = 2; i <= z; i++) {
if (check(i, n, s)) {
out.println(i);
return;
}
}
if (n < s) {
out.println(-1);
return;
}
if (n == s) {
out.println(n + 1);
return;
}
long x = n - s, y = x / z + 1;
for (long i = y; i >= 1; i--) {
if (x % i == 0 && s - i >= 0 && s - i < x / i + 1 && i < x / i + 1) {
out.println(x / i + 1);
return;
}
}
out.println(-1);
}
public boolean check(long base, long n, long s) {
long res = 0;
while (n > 0) {
res += n % base;
n /= base;
}
if (res == s) {
return true;
} else {
return false;
}
}
}
//IO
static class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
}
}
发现一个按照D改编的原题jjgg的难题
AC代码:
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
LL n, s;
cin >> n >> s;
if (n < s) {
cout << "-1\n";
exit(0);
}
if (n == s) {
cout << n + 1 << '\n';
exit(0);
}
LL ans = 1999999999999LL;
LL p = n - s;
function<LL(LL)> check = [&](LL z) {
z++;
LL sum = 0, x = n;
while (x) {
sum += x % z;
x /= z;
}
return sum;
};
for (LL i = 1; i * i <= p; i++) {
if (p % i == 0) {
if (check(i) == s) {
ans = min(ans, i + 1);
}
if (check(p / i) == s) {
ans = min(ans, p / i + 1);
}
}
}
if (ans != 1999999999999LL) {
cout << ans << '\n';
} else {
cout << "-1\n";
}
return 0;
}