当前位置: 首页 > news >正文

蓝桥杯集训·每日一题Week1

前缀和(Monday)

AcWing 3956. 截断数组(每日一题)

在这里插入图片描述
思路:

首先可以预处理出前缀和。判断数组长度如果小于 333 或者前 nnn 项不是 333 的倍数,则可以直接输出 000
否则就枚举所有 s[i]=s[n]3s[i] = \cfrac{s[n]}{3}s[i]=3s[n],以及 s[i]=2s[n]3s[i] = \cfrac{2s[n]}{3}s[i]=32s[n] 的点,统计数量再相乘,最后输出即可。

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;/*** @Description* @Author: PrinceHan* @CreateTime: 2023/3/10 9:25*/
public class Main {static final int N = 100010;static int[] s = new int[N];static int n;static long res;static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static StreamTokenizer in = new StreamTokenizer(br);static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));public static int nextInt() throws IOException {in.nextToken();return (int) in.nval;}public static void main(String[] args) throws IOException {n = nextInt();for (int i = 1; i <= n; i++) {s[i] = nextInt();s[i] += s[i - 1];}int cnt = 0;if (n < 3 || s[n] % 3 != 0) {out.println(0);} else {for (int i = 2; i <= n - 1; i++) {if (s[i - 1] == s[n] / 3) cnt++;if (s[i] == s[n] * 2 / 3) res += cnt;}out.println(res);}out.flush();}}

AcWing 795. 前缀和

在这里插入图片描述
思路:
前缀和以 O(1)O(1)O(1) 的复杂度求出一段区间的和。

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;/*** @Description* @Author: PrinceHan* @CreateTime: 2023/2/25 9:10*/
public class Main {static final int N = 100005;static int n, m;static int[] a = new int[N], s = new int[N];public static void main(String[] args) throws IOException {BufferedReader in = new BufferedReader(new InputStreamReader(System.in));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));String[] nm = in.readLine().split(" ");n = Integer.parseInt(nm[0]);m = Integer.parseInt(nm[1]);String[] arr = in.readLine().split(" ");for (int i = 1; i <= n; i++) {a[i] = Integer.parseInt(arr[i - 1]);s[i] = a[i] + s[i - 1];}while (m-- != 0) {int l, r;String[] lr = in.readLine().split(" ");l = Integer.parseInt(lr[0]);r = Integer.parseInt(lr[1]);out.println(s[r] - s[l - 1]);}out.flush();}
}

AcWing 796. 子矩阵的和

在这里插入图片描述
代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;/*** @Description* @Author: PrinceHan* @CreateTime: 2023/2/25 9:22*/
public class Main {static final int N = 1005;static int n, m, q;static int[][] s = new int[N][N];public static void main(String[] args) throws IOException {BufferedReader in = new BufferedReader(new InputStreamReader(System.in));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));String[] nm = in.readLine().split(" ");n = Integer.parseInt(nm[0]);m = Integer.parseInt(nm[1]);q = Integer.parseInt(nm[2]);for (int i = 1; i <= n; i++) {String[] sub = in.readLine().split(" ");for (int j = 1; j <= m; j++) {s[i][j] = Integer.parseInt(sub[j - 1]);}}for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];}}while (q-- != 0) {int x1, y1, x2, y2;String[] idx = in.readLine().split(" ");x1 = Integer.parseInt(idx[0]);y1 = Integer.parseInt(idx[1]);x2 = Integer.parseInt(idx[2]);y2 = Integer.parseInt(idx[3]);out.println(s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]);}out.flush();}
}

AcWing 99. 激光炸弹

在这里插入图片描述
思路:

典型的子矩阵的和的问题,首先对输入的 RRR 的范围进行限制,R=min(R,5001)R = min(R, 5001)R=min(R,5001),接着初始化子矩阵的和。接着枚举在 R×RR × RR×R 的范围内,价值的最大值。

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;/*** @Description* @Author: PrinceHan* @CreateTime: 2023/2/25 11:29*/
public class Main {static final int N = 5002;static int[][] s = new int[N][N];public static void main(String[] args) throws IOException {BufferedReader in = new BufferedReader(new InputStreamReader(System.in));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));String[] nr = in.readLine().split(" ");int n = Integer.parseInt(nr[0]), r = Integer.parseInt(nr[1]);r = Math.min(5001, r);for (int i = 1; i <= n; i++) {String[] t = in.readLine().split(" ");int x = Integer.parseInt(t[0]), y = Integer.parseInt(t[1]), w = Integer.parseInt(t[2]);s[x + 1][y + 1] += w;}for (int i = 1; i <= 5001; i++) {for (int j = 1; j <= 5001; j++) {s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];}}int max = 0;for (int i = r; i < N; i++) {for (int j = r; j < N; j++) {max = Math.max(s[i][j] - s[i - r][j] - s[i][j - r] + s[i - r][j - r], max);}}out.println(max);out.flush();}
}

AcWing 1230. K倍区间

在这里插入图片描述
思路:

暴力做即使加上前缀和的优化也需要 O(N2)O(N^2)O(N2) 的时间复杂度,在本题的规模下要超时,因此需要独辟蹊径。

容易想到,如果两个数模 nnn 同余,那么这两个数的差值是 nnn 的倍数。所以可以记录前缀和模 kkk 的余数,计算余数相同的前缀和的个数,任选两个前缀和的差值即为 kkk 的倍数,这样只用 O(N)O(N)O(N) 的时间复杂度就可以计算出 KKK 倍区间的数目。

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;/*** @Description* @Author: PrinceHan* @CreateTime: 2023/2/25 11:04*/
public class Main {static final int N = 100005;static int[] s = new int[N];static int[] mod = new int[N];static long ans;static int n, k;public static void main(String[] args) throws IOException {BufferedReader in = new BufferedReader(new InputStreamReader(System.in));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));String[] nk = in.readLine().split(" ");n = Integer.parseInt(nk[0]);k = Integer.parseInt(nk[1]);// 余数为0先赋值为1,当区间和为前缀和时,需要用到mod[0] = 1;for (int i = 1; i <= n; i++) {s[i] = Integer.parseInt(in.readLine().split(" ")[0]);s[i] += s[i - 1];s[i] %= k;mod[s[i]]++;}for (int i = 0; i <= k - 1; i++) {ans += (long) mod[i] * (mod[i] - 1) / 2;}out.println(ans);out.flush();}
}

差分(Tuesday)

AcWing 3729. 改变数组元素(每日一题)

在这里插入图片描述
思路:

分析只,只要执行一次操作 222,数组元素都会变为 111,所以可以用差分构造每个数的操作 222 的次数,如果大于 111,该数就为 111

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;/*** @Description* @Author: PrinceHan* @CreateTime: 2023/2/28 14:21*/
public class Main {static final int N = 200005;static int t, n;// b记录操作的次数static int[] b = new int[N];public static void main(String[] args) throws IOException {BufferedReader in = new BufferedReader(new InputStreamReader(System.in));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));String T = in.readLine().split(" ")[0];t = Integer.parseInt(T);while (t-- != 0) {Arrays.fill(b, 0);String s = in.readLine().split(" ")[0];n = Integer.parseInt(s);String[] arr = in.readLine().split(" ");int x;for (int i = 1; i <= n; i++) {x = Integer.parseInt(arr[i - 1]);if (x == 0) continue;else if (x <= i) {insert(i - x + 1, i, 1);}else insert(1, i, 1);}for (int i = 1; i <= n; i++) {b[i] += b[i - 1];out.print((b[i] > 0 ? 1 : 0) + " ");}out.println();out.flush();}}public static void insert(int l, int r, int c) {b[l] += c;b[r + 1] -= c;}
}

AcWing 797. 差分

在这里插入图片描述

给区间[l, r]中的每个数加上c:B[l] += c, B[r + 1] -= c
#include<iostream>
using namespace std;const int N = 1e6 + 5;
int a[N], q[N];void insert(int l, int r, int c)
{b[l] += c;b[r + 1] -= c;
}
int main()
{int n, m;scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++)scanf("%d", &a[i]);//构造差分数组bfor (int i = 1; i <= n; i++)insert(i, i, a[i]);while (m --){int l, r, c;scanf("%d%d%d", &l, &r, &c);insert(l, r, c);}for (int i = 1; i <= n; i++)b[i] += b[i - 1];for (int i = 1; i <= n; i++)printf("%d ", b[i]);return 0;
}

AcWing 798. 差分矩阵

在这里插入图片描述

给以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵中的所有元素加上c:
S[x1, y1] += c, S[x2 + 1, y1] -= c, S[x1, y2 + 1] -= c, S[x2 + 1, y2 + 1] += c
#include<iostream>
using namespace std;
const int N = 100010;
int n, m, q;
int a[N][N], b[N][N];
void insert(int x1, int y1, int x2, int y2, int c)
{b[x1][y1] += c;b[x2][y1 + 1] -= c;b[x1][y2 + 1] -= c;b[x2 + 1][y2 + 1] += c;
}
int main()
{cin >> n >> m >> q;for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)cin >> a[i][j];for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)insert(i, j, i, j, a[i][j]);while (q--){int x1, y1, x2, y2, c;cin >> x1 >> y1 >> x2 >> y2 >> c;insert(x1, y1, x2, y2, c);}for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)b[i][j] += b[i][j - 1] + b[i - 1][j] - b[i - 1][j - 1];for (int i = 1; i <= n; i++){for (int j = 1; j <= m; j++){cout << b[i][j] << ' ';}cout << endl;}return 0;    
}

二分(Wednesday)

AcWing 1460. 我在哪?(每日一题)

在这里插入图片描述
思路:

本质上是一个寻找最短的不重复子串的问题,可以二分枚举子串的长度。构造子串可以用字符串哈希或者 substring(int fromIndex, int toIndex) 方法,数据范围大的话,建议用字符串哈希。

二分 + 字符串哈希:

核心思想: 将字符串看成P进制数,P的经验值是131或13331,取这两个值的冲突概率低
小技巧: 取模的数用 2642^{64}264,这样直接用 unsigned long long存储,溢出的结果就是取模的结果
注意: 字符串从 111 的位置开始存。前 lll 位字符串的哈希值是 h[l]h[l]h[l],前 rrr 位字符串的哈希值是 h[r]h[r]h[r],则 l∼rl \sim rlr 之间字符串(包含端点)的哈希值可以表示为:
h[l∼r]=h[1∼r]−h[1∼l−1]∗Pr−l+1\begin{aligned} h[l \sim r] &= h[1 \sim r] - h[1 \sim l - 1] * P ^{r - l + 1} \end{aligned} h[lr]=h[1r]h[1l1]Prl+1

在这里插入图片描述

在这里插入图片描述

模板

typedef unsigned long long ull;
ull h[N], p[N]; // h[k]存储字符串前k个字母的哈希值, p[k]存储 P^k mod 2^64// 初始化
p[0] = 1;
for (int i = 1; i <= n; i ++ )
{h[i] = h[i - 1] * P + str[i];p[i] = p[i - 1] * P;
}// 计算子串 str[l ~ r] 的哈希值
ull get(int l, int r)
{return h[r] - h[l - 1] * p[r - l + 1];
}
#include <iostream>
#include <set>
using namespace std;typedef unsigned long long ull;const int N = 105, P = 131;
ull h[N], p[N];
char str[N];
int n;
set<ull> res;ull get(int l, int r)
{return h[r] - h[l - 1] * p[r - l + 1];
}bool check(int mid) 
{res.clear();for (int i = 1; i + mid - 1 <= n; i++){ull t = get(i, i + mid - 1);if (res.find(t) != res.end()) return false;res.insert(t);}return true;
}int main()
{cin >> n;cin >> str + 1;p[0] = 1;for (int i = 1; i <= n; i++) {p[i] = p[i - 1] * P;h[i] = h[i - 1] * P + str[i];}int l = 1, r = 101;// 此模板用于求最小方案while (l < r){int mid = l + r >> 1;if (check(mid)) r = mid;else l = mid + 1;}cout << l << endl;return 0;
}

AcWing 789. 数的范围

在这里插入图片描述
思路:

二分模板一共有两个,分别适用于不同情况。
算法思路:假设目标值在闭区间[l, r]中, 每次将区间长度缩小一半,当l = r时,我们就找到了目标值。

版本1
当我们将区间[l, r]划分成[l, mid][mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。

版本2
当我们将区间[l, r]划分成[l, mid - 1][mid, r]时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。

二分查找时,如果满足当前的 check() 函数,则继续二分。当查找数的左边界时,check() 函数 为 a[mid] >= x,满足条件时,需要更新右边界,r = mid,否则更新左边界 l = mid + 1,此时将区间[l, r]划分成[l, mid][mid + 1, r],用的是第一版本的二分, mid = l + r >> 1

当查找数的右边界时,check() 函数 为 a[mid] <= x,满足条件时,需要更新左边界,l = mid,否则更新右边界 r = mid - 1,此时将区间[l, r]划分成[l, mid - 1][mid, r],用的是第二版本的二分,mid = l + r + 1 >> 1

如果第一轮二分的结果,a[l] != x || a[r] != x,则不存在 x,此时输出 -1 - 1 即可。

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;/*** @Description* @Author: PrinceHan* @CreateTime: 2023/2/25 8:05*/
public class Main {static final int N = 100005;static int[] a = new int[N];static int n, q, k;public static void main(String[] args) throws IOException {BufferedReader in = new BufferedReader(new InputStreamReader(System.in));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));String[] s = in.readLine().split(" ");n = Integer.parseInt(s[0]);q = Integer.parseInt(s[1]);String[] arr = in.readLine().split(" ");for (int i = 0; i < n; i++) a[i] = Integer.parseInt(arr[i]);while (q-- != 0) {int x = Integer.parseInt(in.readLine());int l = 0, r = n - 1;while (l < r) {int mid = l + r >> 1;if (a[mid] >= x) r = mid;else l = mid + 1;}if (a[l] != x) out.println("-1 -1");else {out.print(l + " ");l = 0;r = n - 1;while (l < r) {int mid = l + r + 1 >> 1;if (a[mid] <= x) l = mid;else r = mid - 1;}out.print(r + "\n");}}out.flush();}
}

另外,使用 BufferedReaderPrintWriter 替换 ScannerSystem.out.println()输入输出后,性能有了较大的飞跃。

在这里插入图片描述

AcWing 790. 数的三次方根

在这里插入图片描述
思路:

浮点数二分,最后的精度要求要比给定的要再精确两位。比如结果要求6位小数,则 eps = 1e-8。更新左右边界是将 mid 的值赋值给左右边界,当左右边界的差值小于 精度 eps 时,就结束二分。

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;/*** @Description* @Author: PrinceHan* @CreateTime: 2023/2/25 9:02*/
public class Main {public static void main(String[] args) throws IOException {BufferedReader in = new BufferedReader(new InputStreamReader(System.in));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));double n = Double.parseDouble(in.readLine());double eps = 1e-8;double l = -10000, r = 10000;while (r - l > eps) {double mid = (l + r) / 2;if (mid * mid * mid >= n) r = mid;else l = mid;}out.printf("%.6f", l);out.flush();}
}

AcWing 1227. 分巧克力

在这里插入图片描述
思路:

二分枚举边长的最大值,如果当前边长满足条件,更新左边界 l = mid,否则更新右边界 r = mid - 1,用的是第二个二分模板。

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;/*** @Description* @Author: PrinceHan* @CreateTime: 2023/2/25 10:14*/
public class Main {static final int N = 100005;static int[] h = new int[N], w = new int[N];public static void main(String[] args) throws IOException {BufferedReader in = new BufferedReader(new InputStreamReader(System.in));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));String[] nk = in.readLine().split(" ");int n = Integer.parseInt(nk[0]);int k = Integer.parseInt(nk[1]);int sq = 0;for (int i = 0; i < n; i++) {String[] s = in.readLine().split(" ");h[i] = Integer.parseInt(s[0]);w[i] = Integer.parseInt(s[1]);}int ans = 0;int l = 1, r = 100001;while (l < r) {long num = 0;int mid = l + r + 1>> 1;for (int i = 0; i < n; i++) {num += (long)h[i] / mid * (w[i] / mid);}if (num >= k) {l = mid;}else r = mid - 1;}out.println(l);out.flush();}
}

双指针(Thursday)

AcWing 3768. 字符串删减(每日一题)

在这里插入图片描述
思路:

双指针 iiijjj 分别记录连续的 x...x...x... 子串的开始与结尾,统计重复字串的长度,减到长度为 222 即可,不够 333 可以不用减。

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;/*** @Description* @Author: PrinceHan* @CreateTime: 2023/3/3 14:01*/
public class Main {public static void main(String[] args) throws IOException{BufferedReader in = new BufferedReader(new InputStreamReader(System.in));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));int n = Integer.parseInt(in.readLine());String s = in.readLine();int ans = 0;for (int i = 0; i < n; i++) {// 求连续的x的长度if (s.charAt(i) == 'x') {int j = i + 1;while (j < n && s.charAt(j) == 'x') j++;ans += Math.max(j - i - 2, 0);i = j;}}out.println(ans);out.flush();}
}

AcWing 799. 最长连续不重复子序列

在这里插入图片描述

#include <iostream>
using namespace std;const int N = 100005;
int cnt[N], a[N];
int n;int main()
{cin >> n;int res = 0;for (int i = 0; i < n; i++) cin >> a[i];for (int i = 0, j = 0; i < n; i++){// i为终点,j为起点cnt[a[i]]++;// 遇到重复的元素 j往后移 同时重复的元素的个数-1while (cnt[a[i]] > 1) cnt[a[j++]]--;// 枚举从起点到终点的距离的最大值res = max(res, i - j + 1);}cout << res;return 0;
}

AcWing 800. 数组元素的目标和

在这里插入图片描述

#include <iostream>
using namespace std;
const int N = 100005;
int a[N], b[N];int main()
{int n, m, x;cin >> n >> m >> x;for (int i = 0; i < n; i++) cin >> a[i];for (int j = 0; j < m; j++) cin >> b[j];int i = 0, j = m - 1;//从两端枚举while (i < n && j >= 0){// 和大于x, j向前移动while (a[i] + b[j] > x) j--;// 和小于x, i向后移动while (a[i] + b[j] < x) i++;if (a[i] + b[j] == x) {cout << i << ' ' << j;break;}}return 0;
}

递推(Friday)

AcWing 3777. 砖块(每日一题)

在这里插入图片描述
思路:

首先,如果两种颜色的砖块都是奇数个数,则无法通过翻转变成同一种颜色,如果只有一种颜色,则不用翻转。

可以分两种情况。

  • 都翻转成白色。遇到黑的就翻转,最后判断最后一个砖块是不是白色
  • 都翻转成黑色。遇到白的就翻转,最后判断最后一个砖块是不是黑色

代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;/*** @Description* @Author: PrinceHan* @CreateTime: 2023/3/6 9:18*/
public class Main {static int T, n;static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static StreamTokenizer in = new StreamTokenizer(br);static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));public static int nextInt() throws IOException {in.nextToken();return (int) in.nval;}public static void main(String[] args) throws IOException {T = nextInt();while (T-- != 0) {n = nextInt();int a = 0, b = 0;int[] p1 = new int[205];int[] p2 = new int[205];int[] d1 = new int[205];int[] d2 = new int[205];int cnt1 = 0, cnt2 = 0;String s = br.readLine();// 0白 1黑for (int i = 0; i < n; i++) {if (s.charAt(i) == 'W') {d1[i] = 0;d2[i] = 0;a++;} else {d1[i] = 1;d2[i] = 1;b++;}}if (a % 2 == 1 && b % 2 == 1) out.println(-1);else if (a == 0 || b == 0) out.println(0);else {for (int i = 0; i < n - 1; i++) {// 都换成白的if (d1[i] == 1) {d1[i] = 0;d1[i + 1] = 1 - d1[i + 1];p1[cnt1++] = i + 1;}}for (int i = 0; i < n - 1; i++) {// 都换成黑的if (d2[i] == 0) {d2[i] = 1;d2[i + 1] = 1 - d2[i + 1];p2[cnt2++] = i + 1;}}if (d1[n - 1] != 0) {out.println(cnt2);for (int i = 0; i < cnt2; i++) out.printf("%d ", p2[i]);out.println();} else {out.println(cnt1);for (int i = 0; i < cnt1; i++) out.printf("%d ", p1[i]);out.println();}}}out.flush();}
}

AcWing 95. 费解的开关

在这里插入图片描述

思路:

考虑第一行,有 2n2 ^ n2n 种不同的状态。对于第一行的每个灯的状态,由于每个开关状态的改变会影响上下左右的所有开关的状态,所以在第一行,如果某灯是灭的话,有且仅有该灯下面第二行的开关的改变能影响该灯的状态,也就是说,只有正下方的开关可以改变上一层的状态,第 nnn 行 确定 n+1n + 1n+1 行的状态,第一行确定整个的状态,所以只需要用二进制枚举第一行的状态即可,判断最后一行是否都为亮的,如果都是亮的,则有可行解,再判断可行解与 6 的 关系。

为保证不同的操作方式之间的结果不干扰,一开始要对原始数组先备份,然后再还原。

代码:

import java.util.Arrays;
import java.util.Scanner;/*** @Description* @Author: PrinceHan* @CreateTime: 2023/2/23 15:46*/
public class Main {static final int N = 6;static char[][] g = new char[N][N], backup = new char[N][N];static int n;public static void main(String[] args) {Scanner scanner = new Scanner(System.in);n = scanner.nextInt();while (n-- != 0) {for (int i = 0; i < 5; i++) {String s = scanner.next();g[i] = s.toCharArray();}int res = 10;for (int op = 0; op < (1 << 5); op++) {for (int j = 0; j < 5; j++) {backup[j] = Arrays.copyOf(g[j], 5);}int step = 0;for (int i = 0; i < 5; i++) {if ((op >> i & 1) == 1) {step++;turn(0, i);}}for (int i = 0; i < 4; i++) {for (int j = 0; j < 5; j++) {if (g[i][j] == '0') {step++;turn(i + 1, j);}}}boolean flag = false;for (int i = 0; i < 5; i++) {if (g[4][i] == '0') {flag = true;break;}}if (!flag) res = Math.min(res, step);for (int j = 0; j < 5; j++) {g[j] = Arrays.copyOf(backup[j], 5);}}if (res > 6) System.out.println(-1);else System.out.println(res);}}public static void turn(int x, int y) {int[] dx = {-1, 1, 0, 0, 0}, dy = {0, 0, -1, 1, 0};for (int i = 0; i < 5; i++) {int a = x + dx[i], b = y + dy[i];if (a < 0 || a >= 5 || b < 0 || b >= 5) continue;g[a][b] ^= 1;}}
}

AcWing 116. 飞行员兄弟

在这里插入图片描述
思路:

因为本题规模不大,所以可以通过枚举和位运算来求解,一共有 16 个位置,则有 216=655362^{16} = 65536216=65536 种状态,最后判断开关的状态。用ArrayList 来存储操作,仅当操作数更少的时候,才更新操作集。

代码:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;/*** @Description* @Author: PrinceHan* @CreateTime: 2023/2/23 16:48*/
public class Main {static final int N = 5;static char[][] g = new char[N][N], backup = new char[N][N];static class Node {int x, y;Node(int x, int y) {this.x = x;this.y = y;}}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);ArrayList<Node> ans = new ArrayList<>();for (int i = 0; i < 4; i++) {String s = scanner.next();g[i] = s.toCharArray();}for (int op = 0; op < (1 << 16); op++) {for (int j = 0; j < 4; j++) {backup[j] = Arrays.copyOf(g[j], g[j].length);}ArrayList<Node> tmp = new ArrayList<>();for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {if (((op >> (i * 4 + j)) & 1) == 1) {turn(i, j);tmp.add(new Node(i, j));}}}boolean flag = false;for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {if (g[i][j] == '+') {flag = true;break;}}}if (!flag) {if (ans.isEmpty() || ans.size() > tmp.size()) ans = tmp;}for (int j = 0; j < 4; j++) {g[j] = Arrays.copyOf(backup[j], backup[j].length);}}System.out.println(ans.size());for (Node tmp : ans) {System.out.println((tmp.x + 1) + " " + (tmp.y + 1));}}public static void turn(int x, int y) {for (int i = 0; i < 4; i++) {g[x][i] = g[x][i] == '+' ? '-' : '+';g[i][y] = g[i][y] == '+' ? '-' : '+';}g[x][y] = g[x][y] == '+' ? '-' : '+';}
}

AcWing 1208. 翻硬币

在这里插入图片描述
思路:

本题有不超过100个元素,枚举状态会超时,可以考虑贪心来做,如果两个字符串某个相同位置的元素不相同,就翻转,操作的次数就加一。这样只需要用到 O(N)O(N)O(N) 的时间复杂度。

代码:

import java.util.Scanner;/*** @Description* @Author: PrinceHan* @CreateTime: 2023/2/24 9:54*/
public class Main {static final int N = 105;static char[] s1 = new char[N], s2 = new char[N];static String start, end;static int n, ans;public static void main(String[] args) {Scanner scanner = new Scanner(System.in);start = scanner.next();end = scanner.next();n = start.length();s1 = start.toCharArray();s2 = end.toCharArray();for (int i = 0; i < n - 1; i++) {if (s1[i] != s2[i]) {ans++;turn(i);}}System.out.println(ans);}public static void turn(int u) {s1[u] = s1[u] == '*' ? 'o' : '*';s1[u + 1] = s1[u + 1] == '*' ? 'o' : '*';}
}

相关文章:

蓝桥杯集训·每日一题Week1

前缀和&#xff08;Monday&#xff09; AcWing 3956. 截断数组&#xff08;每日一题&#xff09; 思路&#xff1a; 首先可以预处理出前缀和。判断数组长度如果小于 333 或者前 nnn 项不是 333 的倍数&#xff0c;则可以直接输出 000。 否则就枚举所有 s[i]s[n]3s[i] \cfrac…...

25k的Java开发常问的ThreadLocal问题有哪些?

前言:ThreadLocal问的比较多的是和Synchronized的区别、ThreadLocal被设计弱引用、存储元素的过程、实现线程隔离的原理。 文章目录 ThreadLocalThreadLocal定义ThreadLocal与Synchronized的区别ThreadLocal底层实现ThreadLocalMap存储元素的过程ThreadLocal实现线程隔离的原理…...

R语言基础(四):数据类型

R语言基础(一)&#xff1a;注释、变量 R语言基础(二)&#xff1a;常用函数 R语言基础(三)&#xff1a;运算 5.数据类型 5.1 基本数据类型 R语言基本数据类型大致有六种&#xff1a; 整数Integer、浮点数Numeric、文本(字符串)Character、逻辑(布尔)Logical、复合类型Complex、…...

批处理命令--总结备忘「建议收藏」

批处理命令--总结备忘「建议收藏」 前言1、基础语法:2、批处理基本命令3、实例3.1 打开虚拟目录3.2 以当前时间为文件名,建文件夹3.3 备份postgresql数据库前言 最近用批处理命令做了一些postgresql数据库的备份,打开虚拟环境。。。发现批处理处理一些常用重复工作时真的很…...

面试知识点梳理及相关面试题(十一)-- docker

1. Docker和虚拟机的区别 容器不需要捆绑一整套操作系统&#xff0c;它只需要满足软件运行的最小内核就行了。 传统虚拟机技术是虚拟出一整套硬件后&#xff0c;在其上运行一个完成操作系统&#xff0c;在该系统上再运行所需应用进程容器内的应用进程直接运行于宿主的内核&am…...

k8s--services(微服务)

文章目录一、k8s网络通信service和iptables的关系二、services1.简介2.默认3.IPVS模式的service4.clusterip5.headless6.从外部访问service的三种方式&#xff08;1&#xff09;nodeport&#xff08;2&#xff09;loadbalancer7.metallb一、k8s网络通信 k8s通过CNI接口接入其他…...

【Java开发】设计模式 01:单例模式

1 单例模式介绍单例模式&#xff08;Singleton Pattern&#xff09;是Java中最为基础的设计模式。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单个对…...

10、go工程化与标准库

目录一、用go mod管理工程二、包引入规则三、init调用链四、可见性五、标准库1 - 时间函数2 - 数学计算3 - I/O操作4 - 编码一、用go mod管理工程 初始化项目&#xff1a;go mod init $module_name&#xff0c;$module_name和目录名可以不一样。上述命令会生成go.mod文件 mod…...

【Selenium自动化测试】鼠标与键盘操作

在 WebDriver 中&#xff0c;与鼠标操作相关的方法都封装在ActionChains 类中&#xff0c;与键盘操作相关的方法都封装在Keys类中。下面介绍下这两个类中的常用方法。 鼠标操作 ActionChains类鼠标操作常用方法&#xff1a; context_click()&#xff1a;右击double_click()&…...

自定义javax.validation校验枚举类

枚举类单一情况 package com.archermind.cloud.phone.dto.portal.external.validation.validator;import com.archermind.cloud.phone.dto.portal.external.validation.constraints.EnumValidation; import lombok.extern.slf4j.Slf4j;import javax.validation.ConstraintVali…...

[Java·算法·中等]LeetCode39. 组合总和

每天一题&#xff0c;防止痴呆题目示例分析思路1题解1分析思路2题解2&#x1f449;️ 力扣原文 题目 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形…...

【Linux】vi和vim编辑器

目录主题主题 三种常见模式&#xff1a; 正常模式 以vim 打开一个档案就直接进入一般模式了(这是默认的模式)。在这个模式中&#xff0c;你可以使用[上下左右]按键来移动光标&#xff0c;你可以使用『删除字符』或『删除整行』来处理档案内容&#xff0c;也可以使用「复制、…...

BIO,NIO,AIO

IO模型 用什么样的通道进行数据传输和接收&#xff0c;java支持3种io网络编程模式 BIO NIO AIO BIO 同步阻塞 一个客户端连接对应一个处理线程 BIO示例代码&#xff08;客户端和服务端&#xff09; package com.tuling.bio;import java.io.IOException; import java.net.So…...

代码随想录刷题-数组-有序数组的平方

文章目录有序数组的平方习题暴力排序双指针有序数组的平方 本节对应代码随想录中&#xff1a;代码随想录&#xff0c;讲解视频&#xff1a;有序数组的平方_哔哩哔哩_bilibili 习题 题目链接&#xff1a;977. 有序数组的平方 - 力扣&#xff08;LeetCode&#xff09; 给你一…...

【玩转c++】stack和queue的介绍和模拟实现

本期主题&#xff1a;list的讲解和模拟实现博客主页&#xff1a; 小峰同学分享小编的在Linux中学习到的知识和遇到的问题小编的能力有限&#xff0c;出现错误希望大家不吝赐stack的介绍和使用1.1.stack的介绍1. stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上…...

Linux order(文件、磁盘、网络、系统管理、备份压缩)

1. Linux 文件命令 -rwxrwxrwx chmod&#xff1a;change mode&#xff0c;用于&#xff08;文件所有者或 root &#xff09;变更用户(u:owner g:group o:other a:all)的权限 chmod [OPTION]… MODE[,MODE]… FILE… OPTION -R&#xff1a;递归修改more option&#xff1a;chmod…...

最详细的CentOS7安装Mysql数据库服务

1.查看是否安装mysql: rpm -qa | grep mysql如果有查出来东西&#xff0c;使用命令删除&#xff1a; rpm -e xxx2.检查是否有mysql用户组和mysql用户,没有就添加有就忽略&#xff1a; groups mysql 添加用户组和用户 groupadd mysql && useradd -r -g mysql mysql&a…...

【IoT】项目管理:如何做好端到端的项目管理?

今天主要来谈谈项目管理这个话题。 首先来看一个我在网络上看到的一个关于项目管理的案例或者是段子。 将项目管理的作用及意义非常直观地展示了出来。 有一个植树搞绿化的企业&#xff0c;在公司内部设置有五个部门&#xff0c;分别是&#xff1a; 运输部门&#xff1b;挖坑部…...

渲染十万条数据就把你难住了?不存在的!

虚拟列表的使用场景如果我想要在网页中放大量的列表项&#xff0c;纯渲染的话&#xff0c;对于浏览器性能将会是个极大的挑战&#xff0c;会造成滚动卡顿&#xff0c;整体体验非常不好&#xff0c;主要有以下问题&#xff1a;页面等待时间极长&#xff0c;用户体验差CPU计算能力…...

编程学习的心路历程和困惑回顾

回首入行9年的经历&#xff0c;从大一开始学习C语言和数据结构&#xff0c;老师一直是在用IDE演示程序的编写和运行&#xff0c;我们也就一直在跟黑乎乎的命令行窗口打交道。 后来在一些课程的实验环节&#xff0c;接触到了一些别人编写好的工程代码&#xff0c;知道了Makefile…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...