9.7-携程-笔试
心态爆炸,我真是废物,只做出一道完整的,其他拼凑起来总共不足两道,看了看不少佬都AK了,跟着他们的思路重新整理回顾一下吧。
第一题:排列统计
相邻两数和不为素数的序列个数 类似排列问题,用回溯算法
import java.util.Scanner;
public class Main {
static int[] prime = new int[50];
static int ans;
static int[] val = new int[50];
static int[] a = new int[50];
//打表 生成素数序列 1是素数
public static void generateP(){
prime[1] = 1;
prime[2] = 1;
prime[3] = 1;
for (int i = 4; i <= 40; i++) {
int flag = 1;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
flag = 0;
break;
}
}
prime[i] = flag;
}
}
// 回溯
public static void getAns(int k, int n) {
if (k == n) {
ans++;
return;
}
for (int i = 1; i <= n; i++) {
if (val[i] != 0){
continue;
}
if (k != 0 && prime[a[k - 1] + i] != 0) {
continue;
}
val[i] = 1;
a[k] = i;
getAns(k + 1, n);
val[i] = 0;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
generateP();
getAns(0, n);
System.out.println(ans);
}
}
第二题:you矩阵
给出n*m的字符矩阵,求三点分别为y o u的直角三角形个数,数据范围n,m≤1000行列统计,相乘,注意开long
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int[][] a = new int[1010][1010];
// 5种状态 0-初始化、1-y、2-0、3-u、4-其他
int[][] row = new int[1010][5];
int[][] col = new int[1010][5];
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
// 标记 y、o、u位置
for (int i = 0; i < n; i++) {
String t = scanner.next();
for (int j = 0; j < t.length(); j++) {
if (t.charAt(j) == 'y')
a[i][j] = 1;
else if (t.charAt(j) == 'o')
a[i][j] = 2;
else if (t.charAt(j) == 'u')
a[i][j] = 3;
else
a[i][j] = 4;
}
}
// 标记每行 每列中 y o u出现的次数
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
row[i][a[i][j]]++;
col[j][a[i][j]]++;
}
}
long ans = 0;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(a[i][j] == 1) {
//定位在y点,所在行的o或u数量 * 所在列的u或o数量
ans += row[i][2] * col[j][3];
ans += row[i][3] * col[j][2];
}
if(a[i][j] == 2) {
ans += row[i][1] * col[j][3];
ans += row[i][3] * col[j][1];
}
if(a[i][j] == 3) {
ans += row[i][2] * col[j][1];
ans += row[i][1] * col[j][2];
}
}
}
System.out.println(ans);
}
}
第三题:元素修改
给出n个整数,每次可以选两个分别+1-1,求使得n个数都位于[l, r]的最少操作次数,不存在则输出-1枚举每个数,对小于左边界的数用一个变量记录差值,大于有边界的变量用另一个数记录差值,最后输出两个变量中大的那个
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
long T = scanner.nextLong();
while (T-- > 0) {
long n = scanner.nextLong();
long l = scanner.nextLong();
long r = scanner.nextLong();
long[] v = new long[(int) n];
long sum = 0;
long cnt1 =0;
long cnt2 =0;
for (int i = 0; i < n; i++) {
v[i] = scanner.nextLong();
sum += v[i];
if(v[i]>r){
cnt1+=v[i]-r;
}else if(v[i]<l){
cnt2+=l-v[i];
}
}
// 边界判断
if (sum < l*n || sum > r*n){
System.out.println(-1);
}else {
System.out.println(Math.max(cnt1, cnt2));
}
}
scanner.close();
}
}
第四题:好串
给一个0和1组成的字符串,求子串中有多少“好串”。对“好串”的定义是:所有的前缀子串中,0的数量全部严格大于1的数量。
参考这位大佬的代码:https://www.nowcoder.com/discuss/529398383690137600维护前缀和,遇到0加一,遇到1减一
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String a = scanner.next();
long ans = 0;
int t = 0;
for (int i = 0; i < a.length(); i++) {
if (a.charAt(i) == '0') {
if (t < 0) {
t = 0;
}
t++;
if (t > 0) {
ans += t;
}
} else if (a.charAt(i) == '1') {
t--;
if (t > 0) {
ans += t;
}
}
}
System.out.println(ans);
}
}

