遍历判断即可
下面代码写繁琐了,其实只需要判断不是 空格和换行就可以
import java.io.*;
import java.util.*;
import java.lang.*;
public class Main {
private static int N = (int) 1e6 + 10, n, m;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
char[] s = sc.nextLine().toCharArray();
long ans = 0;
for (int i = 0; i < s.length; i++) {
if (('a' <= s[i] && s[i] <= 'z') || ('0' <= s[i] && s[i] <= '9') || ('A' <= s[i] && s[i] <= 'Z'))
ans++;
}
System.out.println(ans);
}
}
import java.io.*;
import java.util.*;
import java.lang.*;
public class Main {
private static int N = (int) 1e6 + 10, n, m;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
char[] s = sc.nextLine().toCharArray();
long ans = 0;
for (int i = 0; i < s.length; i++) {
if (s[i] != ' ' && s[i] != '\n')
ans++;
}
System.out.println(ans);
}
}
模拟,但是要注意 int溢出
注意一点:中立兵营也可以放兵,所以最后遍历的时候直接遍历整个数组判断即可
/**
* @author :Changersh
* @date : 2023/1/14 15:44
*/
import java.io.*;
import java.util.*;
import java.lang.*;
public class Main {
private static int N = (int) 1e6 + 10, n, m, p, s1, s2;
private static long ans = 0, mn = 0, l = 0, r = 0;
private static long[] a = new long[N];
public static void main(String[] args) {
n = sc.nextInt();
for (int i = 1; i <= n; i++) a[i] = sc.nextLong();
m = sc.nextInt(); // 中立号
p = sc.nextInt(); // 要增加的兵营号
s1 = sc.nextInt(); // 数量
s2 = sc.nextInt(); // 数量
a[p] += s1;
for (int i = 1; i < m; i++) l += a[i] * (m - i);
for (int i = m + 1; i <= n; i++) r += a[i] * (i - m);
mn = Long.MAX_VALUE;
for (int i = 1; i <= n; i++) {
long t = (long) s2 * (m - i);
if (Math.abs(r - l - t) < mn) {
mn = Math.abs(r - l - t);
ans = i;
}
}
pw.println(ans);
pw.close();
}
}
先对教室数组求差分,然后二分订单号,找到最小的不满足的订单号。
用 c 做差分的临时数组
/**
* @author :Changersh
* @date : 2023/3/26 15:44
* 二分答案
*/
import java.io.*;
import java.util.*;
import java.lang.*;
public class Main {
private static int N = (int) 1e6 + 10, n, m, ans = 0, idx = 0;
private static int[] a = new int[N], c = new int[N];
private static int[][] b = new int[N][3];
public static void main(String[] args) {
n = sc.nextInt();
m = sc.nextInt();
for (int i = 1; i <= n; i++) a[i] = sc.nextInt();
for (int i = 1; i <= m; i++) {
b[i][0] = sc.nextInt();
b[i][1] = sc.nextInt();
b[i][2] = sc.nextInt();
}
for (int i = n; i >= 1; i--) a[i] -= a[i - 1];
int l = 1, r = m + 1;
while (l < r) {
int mid = l + ((r - l) >> 1);
if (check(mid)) r = mid;
else l = mid + 1;
}
if (check(r)) pw.println(-1 + "\n" + r);
else pw.println("0");
pw.close();
}
// 差分 + 前缀和 判断是否合格???
private static boolean check(int x) {
for (int i = 1; i <= n; i++) c[i] = a[i]; // 复制数组
for (int i = 1; i <= x; i++) {
c[b[i][1]] -= b[i][0];
c[b[i][2] + 1] += b[i][0];
}
long sum = 0;
for (int i = 1; i <= n; i++) {
sum += c[i];
if (sum < 0) return true;
}
return false;
}
}
原来用的数组模拟队列,结果一直有一个点过不去,现在也没看出来哪里错误了,模拟的队列应该错了,换成了 acwing 的模拟队列,过了
换成队列之后,过了
/**
* @author :Changersh
* @date : 2023/1/14 15:44
*/
import java.io.*;
import java.util.*;
import java.lang.*;
public class Main {
private static int N = 1010, n, m, ans = 0, idx = 0, x;
private static boolean[] vis = new boolean[N];
private static ArrayDeque<Integer> ad = new ArrayDeque<>();
public static void main(String[] args) {
m = sc.nextInt();
n = sc.nextInt();
for (int i = 0; i < n; i++) {
x = sc.nextInt();
if (vis[x]) continue;
ad.addLast(x);
vis[x] = true;
ans++;
while (ad.size() > m) {
int t = ad.pollFirst();
vis[t] = false;
}
}
pw.println(ans);
pw.close();
}
}
import java.io.*;
import java.util.*;
import java.lang.*;
public class Main {
private static int N = 1010, n, m, ans = 0, idx = 0, x, hh = 0, tt = -1;
private static boolean[] vis = new boolean[N];
private static int[] t = new int[N]; // 模拟队列
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
m = sc.nextInt();
n = sc.nextInt();
for (int i = 0; i < n; i++) {
x = sc.nextInt();
if (vis[x]) continue;
ans++;
t[++tt] = x;
vis[x] = true;
int p = (tt - hh + 1); // 要插入的位置
if (p > m) vis[t[hh++]] = false;
}
System.out.println(ans);
}
}
可以发现,当 x 是奇数时,就不是优秀的拆分,偶数都是优秀的拆分
拆分出来的是 不相同的 2 的次幂,也就是 x 二进制上的每一位,我们用 low_bit(x) 循环取数,放置在数组中,最后倒序输出即可
import java.io.*;
import java.util.*;
import java.lang.*;
public class Main {
private static int N = 1010, n, m, ans = 0, idx = 0;
private static int[] a = new int[N];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
if ((n & 1) == 1) System.out.println("-1");
else {
while (n > 0) {
int t = low_bit(n);
n -= t;
a[idx++] = t;
}
for (int i = idx - 1; i >= 0; i--) System.out.print(a[i] + " ");
}
}
private static int low_bit(int x) {
return x & -x;
}
}
题意是先给出获奖概率,然后按次序给出分数,人数每次加一,最少得有一个人获奖。
每次多一个人之后,就给出当前的分数线(即可以获奖的最低分数)
因为分数总共就 600 分,我们可以倒序遍历,查找获奖的分数线,当前人数总和 >= 获奖人数时,这个分数就是分数线
/**
* @author :Changersh
* @date : 2023/3/26 15:44
*/
import java.io.*;
import java.util.*;
import java.lang.*;
public class Main {
private static int N = (int) 1e5 + 10, n, w, x, y, sum, t;
private static int[] a = new int[610]; // 记录每个数的数量
public static void main(String[] args) {
n = sc.nextInt();
w = sc.nextInt(); // 输入的是个整数,需要 / 100 才是小数概率
for (int i = 1; i <= n; i++) {
x = i * w / 100; // 获奖人数
sum = 0;
if (x < 1) x = 1; // 获奖人数不能小于 1
t = sc.nextInt(); // 读入选手的分数
a[t]++; // 分数标记 + 1
for (int j = 600; j >= 0; j--) {
sum += a[j];
if (sum >= x) {
pw.print(j + " "); // 输出获奖分数线,所以只需要输出最小的分数即可
break;
}
}
}
pw.close();
}
}
注意细节,左上角一定是有颜色的
/**
* @author :Changersh
* @date : 2023/3/26 15:44
*/
import java.io.*;
import java.util.*;
import java.lang.*;
public class Main {
private static final int inf = Integer.MAX_VALUE;
private static int N = 1010, n, m, ans = Integer.MAX_VALUE;
private static int[][] g = new int[N][N]; // 颜色
private static int[] dx = {-1, 0, 1, 0}, dy = {0, 1, 0, -1};
private static int[][] dis = new int[N][N];
public static void main(String[] args) {
n = sc.nextInt();
m = sc.nextInt();
for (int i = 0; i < N; i++) Arrays.fill(dis[i], 0x3f3f3f3f);
int x, y, c;
while (m-- > 0) {
x = sc.nextInt();
y = sc.nextInt();
c = sc.nextInt();
g[x][y] = c + 1; // 1 红色,2 黄色,0 无色
}
dfs(1, 1, 0, false); // 从(1, 1) 开始,目前总金币是 0,没有使用变色
if (ans == inf) pw.println(-1);
else pw.println(ans);
pw.close();
}
private static void dfs(int x, int y, int sum, boolean magic) {
if (x <= 0 || x > n || y <= 0 || y > n) return; // 越界
if (g[x][y] == 0) return;
if (sum >= dis[x][y]) return; // 没必要了
dis[x][y] = sum;
if (x == n && y == n) {
if (sum < ans) ans = sum;
return;
}
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx <= 0 || nx > n || ny <= 0 || ny > n) continue;
if (g[nx][ny] != 0) {
if (g[x][y] == g[nx][ny]) dfs(nx, ny, sum, false);
else dfs(nx, ny, sum + 1, false);
} else if (g[nx][ny] == 0 && !magic) {
g[nx][ny] = g[x][y];
dfs(nx, ny, sum + 2, true);
g[nx][ny] = 0;
}
}
}
}