简单的暴力循环求解
35813063
/**
* @ProjectName: study3
* @FileName: A
* @author:HWJ
* @Data: 2023/9/4 7:46
* // 1980
*/
public class A {
public static void main(String[] args) {
int[] days = {0,31, 28,31,30,31,30,31,31,30,31,30,31};
int[] days2 = {0,31, 29,31,30,31,30,31,31,30,31,30,31};
long total = 0;
for (int i = 2000; i < 2000000; i++) {
for (int j = 1; j <= 12; j++) {
if((i % 4 == 0 && i % 100 != 0) || i % 400 == 0){
for (int k = 1; k <= days2[j]; k++) {
if (i % j == 0 && i % k == 0){
total++;
}
}
}else {
for (int k = 1; k <= days[j]; k++) {
if (i % j == 0 && i % k == 0){
total++;
}
}
}
}
}
System.out.println(++total);
}
}
一个简单的暴力递归求解
30528
/**
* @ProjectName: study3
* @FileName: B
* @author:HWJ
* @Data: 2023/9/4 8:04
*/
public class B {
public static int ans = 0;
public static int[][] map = new int[6][6];
public static void main(String[] args) {
map[5] = new int[]{0,1,0,1,0,1};
dfs(1, 5);
System.out.println(ans);
}
public static void dfs(int i, int n){
if (n == 1){
if (map[1][1] == 1){
++ans;
}
}else {
if(i < n){
map[n-1][i] = map[n][i] & map[n][i+1];
dfs(i + 1, n);
map[n-1][i] = map[n][i] | map[n][i+1];
dfs(i + 1, n);
map[n-1][i] = map[n][i] ^ map[n][i+1];
dfs(i + 1, n);
}else {
dfs(1, n-1);
}
}
}
}
有一个长度为 n 的数组(n 是 10 的倍数),每个数 ai 都是区间 [0, 9] 中的整数。小明发现数组里每种数出现的次数不太平均,而更改第 i 个数的代价为bi,他想更改若干个数的值使得这 10 种数出现的次数相等(都等于n/10),请问代价和最少为多少。
输入的第一行包含一个正整数 n 。
接下来 n 行,第 i 行包含两个整数 ai , bi ,用一个空格分隔。
输出一行包含一个正整数表示答案。
10 1 1 1 2 1 3 2 4 2 5 2 6 3 7 3 8 3 9 4 10
27
只更改第 1, 2, 4, 5, 7, 8 个数,需要花费代价 1 + 2 + 4 + 5 + 7 + 8 = 27 。
对于 20% 的评测用例,n ≤ 1000;
对于所有评测用例,n ≤ 100000, 0 < bi ≤ 2 × 10^5
因为它每个数字只能是[0,9],并且要满足个数为n/10,所以我们可以构建十个数组(数组大小为n/10),来分别存放这十个数字当中不需要修改的数,如果这十个数组,没有满,就直接存放,如果满了,则将这个数组进行排序,然后用当前的b和数组第一个数进行比较,将大的数存入数组,然后total += 小的数。这样我们就可以找到最小花费。
import java.util.Arrays;
import java.util.Scanner;
/**
* @ProjectName: study3
* @FileName: C
* @author:HWJ
* @Data: 2023/9/4 8:33
*/
public class C {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
long total = 0;
int n = input.nextInt();
int l = n / 10;
int[] m0 = new int[l];
int[] m1 = new int[l];
int[] m2 = new int[l];
int[] m3 = new int[l];
int[] m4 = new int[l];
int[] m5 = new int[l];
int[] m6 = new int[l];
int[] m7 = new int[l];
int[] m8 = new int[l];
int[] m9 = new int[l];
int n0 = 0;
int n1 = 0;
int n2 = 0;
int n3 = 0;
int n4 = 0;
int n5 = 0;
int n6 = 0;
int n7 = 0;
int n8 = 0;
int n9 = 0;
for (int i = 0; i < n; i++) {
int a = input.nextInt();
int b = input.nextInt();
if(a == 0){
if(n0 < l){
m0[n0++] = b;
}else {
Arrays.sort(m0);
if(b >= m0[0]){
total += m0[0];
m0[0] = b;
}else {
total += b;
}
}
}
if(a == 1){
if(n1 < l){
m1[n1++] = b;
}else {
Arrays.sort(m1);
if(b >= m1[0]){
total += m1[0];
m1[0] = b;
}else {
total += b;
}
}
}
if(a == 2){
if(n2 < l){
m2[n2++] = b;
}else {
Arrays.sort(m2);
if(b >= m2[0]){
total += m2[0];
m2[0] = b;
}else {
total += b;
}
}
}
if(a == 3){
if(n3 < l){
m3[n3++] = b;
}else {
Arrays.sort(m3);
if(b >= m3[0]){
total += m3[0];
m3[0] = b;
}else {
total += b;
}
}
}
if(a == 4){
if(n4 < l){
m4[n4++] = b;
}else {
Arrays.sort(m4);
if(b >= m4[0]){
total += m4[0];
m4[0] = b;
}else {
total += b;
}
}
}
if(a == 5){
if(n5 < l){
m5[n5++] = b;
}else {
Arrays.sort(m5);
if(b >= m5[0]){
total += m5[0];
m5[0] = b;
}else {
total += b;
}
}
}
if(a == 6){
if(n6 < l){
m6[n6++] = b;
}else {
Arrays.sort(m6);
if(b >= m6[0]){
total += m6[0];
m6[0] = b;
}else {
total += b;
}
}
}
if(a == 7){
if(n7 < l){
m7[n7++] = b;
}else {
Arrays.sort(m7);
if(b >= m7[0]){
total += m7[0];
m7[0] = b;
}else {
total += b;
}
}
}
if(a == 8){
if(n8 < l){
m8[n8++] = b;
}else {
Arrays.sort(m8);
if(b >= m8[0]){
total += m8[0];
m8[0] = b;
}else {
total += b;
}
}
}
if(a == 9){
if(n9 < l){
m9[n9++] = b;
}else {
Arrays.sort(m9);
if(b >= m9[0]){
total += m9[0];
m9[0] = b;
}else {
total += b;
}
}
}
}
System.out.println(total);
}
}
小蓝拥有 n × n 大小的棋盘,一开始棋盘上全都是白子。小蓝进行了 m 次操作,每次操作会将棋盘上某个范围内的所有棋子的颜色取反 (也就是白色棋子变为黑色,黑色棋子变为白色)。请输出所有操作做完后棋盘上每个棋子的颜色。
输入的第一行包含两个整数 n, m,用一个空格分隔,表示棋盘大小与操作数。
接下来 m 行每行包含四个整数 x1, y1, x2, y2,相邻整数之间使用一个空格分隔,表示将在 x1 至 x2 行和 y1 至 y2 列中的棋子颜色取反。
输出 n 行,每行 n 个 0 或 1 表示该位置棋子的颜色。如果是白色则输出 0,否则输出 1 。
3 3 1 1 2 2 2 2 3 3 1 1 3 3
001 010 100
对于 30% 的评测用例,n m ≤ 500 ;
对于所有评测用例,1 ≤ n, m ≤ 2000 ,1 ≤ x1 ≤ x2 ≤ n ,1 ≤ y1 ≤ y2 ≤ m 。
【思路解析】
创建一个棋盘,初始化棋盘为0,然后当需要取反时取反,这个逻辑很简单,但是因为输出量很大,我们需要减少输出时间来防止运行超时。需要用到PrintWriter。
【代码实现】
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Scanner;
/**
* @ProjectName: study3
* @FileName: D
* @author:HWJ
* @Data: 2023/9/4 9:09
*/
public class D {
public static int[][] map;
// 这样的输出更节约时间,在输出量大导致运行时间超时的时候,可以用这样的方法来解决
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int m = input.nextInt();
map = new int[n][n];
for (int i = 0; i < m; i++) {
int x1 = input.nextInt();
int y1 = input.nextInt();
int x2 = input.nextInt();
int y2 = input.nextInt();
reverse(x1, y1, x2, y2);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
pw.print(map[i][j]);
}
pw.println();
}
pw.flush();
}
public static void reverse(int x1, int y1, int x2, int y2){
for (int j = x1 - 1; j <= x2 - 1; j++) {
for (int k = y1 - 1; k <= y2 - 1; k++) {
if(map[j][k] == 1){
map[j][k] = 0;
}else {
map[j][k] = 1;
}
}
}
}
}
给定 a, b,求 1 ≤ x < ab 中有多少个 x 与 ab 互质。由于答案可能很大,你只需要输出答案对 998244353 取模的结果。
输入一行包含两个整数分别表示 a, b,用一个空格分隔。
输出一行包含一个整数表示答案。
2 5
16
对于 30% 的评测用例,ab ≤ 106 ;
对于 70% 的评测用例,a ≤ 106,b ≤ 109 ;
对于所有评测用例,1 ≤ a ≤ 109,1 ≤ b ≤ 1018 。
这里需要使用欧拉函数。
/**
* @ProjectName: study3
* @FileName: E
* @author:HWJ
* @Data: 2023/9/4 10:15
*/
public class E {
static int mod = 998244353;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
long a = input.nextLong();
long b = input.nextLong();
long m = 1;
long k = b;
for (; k >= 1; k >>= 1, a = a * a % mod) {
if ((k & 1) == 1) {
m = m * a % mod;
}
}
System.out.println(oula(m));
}
public static long oula(long num) {
long total = num;
for (long i = 2; i < num; i++) {
if (num % i == 0) {
while (num % i == 0) {
num /= i;
}
total = total - total / i;
}
}
if(num > 1){
total = total - total / num;
}
return total;
}
}
给定 n 个数 Ai,问能满足 m! 为∑ni=1(Ai!) 的因数的最大的 m 是多少。其中 m! 表示 m 的阶乘,即 1 × 2 × 3 × · · · × m。
输入的第一行包含一个整数 n 。
第二行包含 n 个整数,分别表示 Ai,相邻整数之间使用一个空格分隔。
输出一行包含一个整数表示答案。
3 2 2 2
3
对于 40% 的评测用例,n ≤ 5000 ;
对于所有评测用例,1 ≤ n ≤ 105 1 ≤ Ai ≤ 109 。
对于一个阶乘来说,如果n > m,则n!一定是m! 的倍数,所以对于给定的n个数Ai的和来说,他们的和一定是min(Ai)的倍数。所以我们需要找到这个最小的maxV, 当它达到maxV + 1个时,他就可以变为(maxV + 1)!,我们需要模拟这个阶乘类和的过程。
import java.util.HashMap;
import java.util.Scanner;
/**
* @ProjectName: study3
* @FileName: F
* @author:HWJ
* @Data: 2023/9/4 19:19
*/
public class F {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
HashMap map = new HashMap<>();
int maxV = 1000000000;
for (int i = 0; i < n; i++) {
int a = input.nextInt();
maxV = Math.min(maxV, a);
if (!map.containsKey(a)) {
map.put(a, 1);
} else {
map.put(a, map.get(a) + 1);
}
while (map.get(a) % (a + 1) == 0) {
if (map.containsKey(a + 1)){
map.put(a + 1, map.get(a + 1) + map.get(a) / (a + 1));
}else {
map.put(a + 1, map.get(a) / (a + 1));
}
map.put(a, 0);
if (maxV == a) {
maxV = a + 1;
}
a++;
}
}
System.out.println(maxV);
}
}
小蓝正计划进行一次漫长的旅行。小蓝计划开车完成这次旅行。显然他在途中需要加油,否则可能无法完成这次旅行。
小蓝要依次经过 n 个地点,其中从第 i − 1 个地点到达第 i 个地点需要消耗 Disi 升油。小蓝经过的每个地点都有一个加油站,但每个加油站的规定也不同。在第 i 个加油站加 1 升油需要 Costi 的费用,且在这个加油站最多只能加 Limi 升油。
小蓝的车的油箱也有容量限制,他的车上最多只能装载 m 升油。
一开始小蓝的油箱是满的,请问小蓝需要准备多少钱才能顺利完成他的旅行计划。如果小蓝按给定条件无论准备多少钱都不能完成他的旅行计划,请输出 −1 。
输入的第一行包含两个整数 n m ,用一个空格分隔。
接下来 n 行每行包含 3 个整数 Disi Costi Limi,相邻整数之间使用一个空 格分隔。
输出一行包含一个整数表示答案。
复制
4 5 2 9 2 4 5 6 3 2 2 4 1 3
复制
38
对于 30% 的评测用例,n Disi Costi Limi m ≤ 300 ;
对于 60% 的评测用例,n Disi Costi Limi m ≤ 5000 ;
对于所有评测用例,1 ≤ n ≤ 2 × 105,1 ≤ Disi Limi m ≤ 109,1 ≤ Costi ≤ 40000 。
这天,小蓝在二维坐标系的点 (X, Y) 上放了一个太阳,看做点光源。
他拿来了 n 条线段,将它们平行于 x 轴放置在了坐标系中,第 i 条线段的左端点在 xi , yi,长度为 li。线段之间不会有重合或部分重合的情况(但可能出现端点相交)。小蓝想知道有多少条线段能被太阳照亮(一条线段有长度大于 0的部分被照亮就算)
输入的第一行包含三个正整数 n, X, Y,相邻整数之间使用一个空格分隔。
接下来 n 行,第 i 行包含三个整数 xi , yi , li,相邻整数之间使用一个空格分隔。
输出一行包含一个正整数表示答案。
复制
3 10 2000000 5 3 5 6 2 4 0 1 10
复制
2
第一条线段在最上面被照亮,第二条线段被第一条完全挡住,第三条线段左边的一段能被照亮。
对于 30% 的评测用例,n ≤ 1000 ;
对于所有评测用例,1 ≤ n ≤ 100000, 0 ≤ xi , X ≤ 107 , 0 < yi ≤ 105 , 0 < li ≤ 100, 106 < Y ≤ 107 。
小蓝正在玩一个攀登高塔的游戏。高塔的层数是无限的,但游戏最多只有 n 回合。
小蓝一开始拥有 m 点能量,在每个回合都有一个值 Ai 表示小蓝的角色状态。小蓝每回合可以选择消费任意点能量 Ci (最低消费 1 点,没有上限),他在这回合将最多可以向上攀爬 Ai · Ci 层。实际攀爬的层数取决于小蓝自己在这回合的表现,不过最差也会向上爬一层。
当某回合小蓝的能量点数耗尽,那么在完成这个回合后,游戏结束。n 回合结束后,不管能量还有没有剩余,游戏都会直接结束。
给出小蓝每回合的 Ai 和自己一开始的能量点数 m。小蓝想知道有多少种不同的可能出现的游玩过程。如果小蓝在两种游玩过程中的任一对应回合花费的能量点数不同或该回合结束时所处层数不同,那么这两种游玩过程就被视为不同。
输入的第一行包含两个整数 n, m,用一个空格分隔。
第二行包含 n 个整数 Ai,相邻整数之间使用一个空格分隔,表示小蓝每回合的状态值。
输出一行包含一个整数表示给定条件下不同游玩过程的数量。由于答案可能很大,你只需要输出答案对 998244353 取模的结果。
复制
9 15 3 2 5 7 1 4 6 8 3
复制
392149233
对于 40% 的评测用例,n ≤ 300,m ≤ 500 ;
对于所有评测用例,1 ≤ n ≤ 2 × 105,n ≤ m ≤ 1018,1 ≤ Ai ≤ 109 。
初始有一个空的 01 串,每步操作可以将 0 或 1 添加在左侧或右侧。也可以对整个串进行反异或操作: 取 s ′ = s ⊕ rev(s),其中 s 是目前的 01 串,⊕ 表示逐位异或,rev(s) 代表将 s 翻转,也就是说取中心位置并交换所有对称的两个位置的字符。例如,rev(0101) = 1010 rev(010) = 010 rev(0011) = 1100。
反异或操作最多使用一次(可以不用,也可以用一次)。
给定一个 01 串 T,问最少需要添加多少个 1 才能从一个空 01 串得到 T。
在本题中 0 可以添加任意个。
输入一行包含一个 01 串表示给定的 T 。
输出一行包含一个整数,表示需要最少添加多少个 1 。
复制
00111011
复制
3
对于 20% 的评测用例,|T| ≤ 10 ;
对于 40% 的评测用例,|T| ≤ 500 ;
对于 60% 的评测用例,|T| ≤ 5000 ;
对于 80% 的评测用例,|T| ≤ 105 ;
对于所有评测用例,1 ≤ |T| ≤ 106,保证 T 中仅含 0 和 1 。