1.乒乓球
获胜规则如下:一方至少赢得11分,且超过对方2分,获得胜利。
小美得a分,小团b分,最理想的情况下,小美至少还要得多少分才可以赢。
样例输入:
30 31
样例输出:
3
参考解答:
import java.util.Scanner;
/**
* @author Halu
* @create 2022-09-03 11:36
*/
public class countGame {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
System.out.print(countGame(a,b));
}
public static int countGame(int a, int b) {
int res = 0;
if (a>=11){
if (a>=b+2){return 0;}
else{return b+2-a;}
}else{ // a<11
if (a>=b+2){return 11-a;}
else if ( (a<b+2) && (b+2>=11) ) return b+2-a;
else if ( (a<b+2) && (b+2<11) ) return 11-a;
}
return res;
}
}
2.二叉树
n个节点的树,里面存字母。判定各个子树含有多少种类型的字母。
输入描述:
输出描述:
样例输入:
6
1 2 2 1 4
ABCCAD
样例输出:
4 3 1 2 1 1
参考解法:
package exer1;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import java.util.Arrays;
import java.util.Scanner;
/**
* @author Halu
* @create 2022-09-04-20:42
*/
class countAlpha {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] relation = new int[n-1];
System.out.println();
for (int i = 0; i <n-1 ; i++) {
relation[i]=in.nextInt();
// System.out.print(relation[i]+" ");
}
in.nextLine();
String s = in.nextLine();
for (int i = 0; i < s.length(); i++) {
// System.out.print(s.charAt(i)+" ");
}
int[] res = countAlpha(n,relation,s);
for (int resNum:res) {
System.out.print(resNum+" ");
}
}
public static int[] countAlpha(int n, int[] relation, String s){
int[] res = new int[n];
boolean[][] graph = new boolean[n][n];//graph用来存relation的父子关系,从父节点可到子节点该位置为true
for (int i = 0; i < n; i++) {
Arrays.fill(graph[i],false);
}
// 遍历relation,把 x=relation[i](父节点),和子节点y=i+2 存到 graph[x][y]中
for (int i = 0; i < n - 1; i++) {
int x = relation[i]-1; // 父
int y = i+1; // 子
graph[x][y] = true;
}
for (int x = 0; x < n; x++) {//遍历1~n节点,找子节点,然后子节点递归
boolean[] used = new boolean[26];
used[s.charAt(x)-'A'] = true;
for (int y = 0; y < n ; y++) {
if (graph[x][y] == true){
char ch = s.charAt(y);
used[ch-'A'] = true;
used=countUsed(y,graph,s,used);
}
}
int sum=0;
for (int i = 0; i < 26; i++) {
if (used[i]==true) sum++;
}
res[x] = sum;
}
return res;
}
public static boolean[] countUsed(int start, boolean[][] graph, String s, boolean[] used){
int n=graph.length;
// 遍历graph
// 维护一个used标记种类
// boolean[] used = new boolean[26];
for (int y = 0; y < n; y++) {
if (graph[start][y] == true){
char ch = s.charAt(y);
used[ch-'A'] = true;
countUsed(y,graph,s,used);
}
}
return used;
}
}
类似参考解答:
力扣1519
class Solution {
public int[] countSubTrees(int n, int[][] edges, String labels) {
/*
后序遍历
*/
List<Integer>[] points = new List[n];
for(int i = 0; i < n; i++){
points[i] = new ArrayList<>();
}
for(int[] p : edges){
points[p[0]].add(p[1]);
points[p[1]].add(p[0]);
}
int[] ls = new int[n];
for(int i = 0; i < n; i++){
ls[i] = labels.charAt(i) - 'a';
}
res = new int[n];
visited = new boolean[n];
visited[0] = true;
dfs(0, points, ls);
return res;
}
int[] res;
boolean[] visited;
private int[] dfs(int i, List<Integer>[] points, int[] ls){
int[] curLs = new int[26];
//添加自身节点
curLs[ls[i]]++;
for(int child : points[i]){
/*
判断是否已经遍历过该节点,如果遍历过,那么跳过
因为这是无向图, 1 可以到 2,2 也可以到 1,因此,当 1 到 2 的时候,我们需要记录 1 已经访问
这样,从 2 出发,就不会再到 1 了
*/
if(visited[child]){
continue;
}
visited[child] = true;
int[] childLs = dfs(child, points, ls);
for(int k = 0; k < 26; k++){
curLs[k] += childLs[k];
}
}
res[i] = curLs[ls[i]];
return curLs;
}
}
9.10 第三次笔试
1.刷题
n个题,小美正序做,小团逆序做。小美速度y题/小时,小团速度x题/小时。获胜规则,谁先写完第k题谁就获得胜利。
- 输入:
第一行表示数据组数T,
接下来T行,每行包括四个正整数n,x,y,k。
- 输出:共T行
小美获胜输出Win
小团获胜输出Lose
平局输出Tie
除法需要注意的点:算速度时间用 double 接收
import java.util.Scanner;
/**
* @author Halu
* @create 2022-09-10 16:38
*/
public class Meituan3 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int[][] nums = new int[N][4];
for (int i = 0; i < 3; i++) {
nums[i][0]=in.nextInt();
nums[i][1]=in.nextInt();
nums[i][2]=in.nextInt();
nums[i][3]=in.nextInt();
}
String[] res = tellWinner(nums);
for (int i = 0; i < res.length; i++) {
System.out.println(res[i]);
}
}
public static String[] tellWinner(int[][] nums){
String[] Winner = new String[nums.length];
for (int i = 0; i < nums.length; i++) {
int n = nums[i][0];
int Vwin = nums[i][1];
int Vlose = nums[i][2];
int k = nums[i][3];
double winTime = (double)k/Vwin;
double loseTime = (double)(n+1-k)/Vlose;
if (winTime<loseTime) Winner[i]= "Win";
else if(winTime>loseTime) Winner[i]= "Lose";
else Winner[i]= "Tie";
}
return Winner;
}
}
// 牛客上的答案:除法转为乘法
Scanner scanner = new Scanner(System.in);
int t = scanner.nextInt();
while(t-->0){
long n = scanner.nextLong();
long x = scanner.nextLong();
long y = scanner.nextLong();
long k = scanner.nextLong();
if (k * y < x * (n - k + 1)) {
System.out.println("Win");
} else if (k * y == x * (n - k + 1)) {
System.out.println("Tie");
} else {
System.out.println("Lose");
}
}
2. 寻宝
// 牛客上的答案
package mt.笔试;
/*
时间限制: 3000MS
内存限制: 589824KB
题目描述:
某天小美进入了一个迷宫探险,根据地图所示,这个迷宫里有无数个房间,序号分别为1、2、3、…、∞,入口房间的序号为1,任意序号为正整数x的房间都与序号2*x和2*x+1的房间之间各有一条路径,但是这些路径是单向的,即只能从序号为x的房间去到序号为2*x或2*x+1的房间,而不能从序号为2*x或2*x+1的房间去到序号为x的房间。在任何时刻小美都可以选择结束探险并离开迷宫,但是离开之后将无法再次进入迷宫。小美还提前了解了迷宫中宝藏的信息,已知宝藏共有n个,其中第 i 个宝藏在序号为pi的房间,价值为wi,且一个房间中可能有多个宝藏。小美为了得到更多的宝藏,需要精心规划路线,她找到你帮忙,想请你帮她计算一下,能获得的宝藏价值和最大值为多少。
输入描述
第一行一个正整数n,表示宝藏数量。
第二行为n个正整数p1, p2,...... pn,其中pi表示第 i 个宝藏在序号为pi的房间。
第三行为n个正整数w1, w2,...... wn,其中wi表示第i个宝藏的价值为wi。
数字间两两有空格隔开
1 ≤ n ≤ 40000, 1 ≤ pi <230, 1 ≤ wi ≤ 106。
输出描述
输出一个正整数表示能获得的宝藏价值之和的最大值。
*/
package ACM_Exercise;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Scanner;
/**
* @author Halu
* @create 2022-09-10 17:14
*/
public class Meituan302 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
long[] pos = new long[n];
long[] value = new long[n];
for (int i = 0; i < n; i++) {
pos[i] = in.nextLong();
}
for (int i = 0; i < n; i++) {
value[i] = in.nextInt();
}
System.out.println(maxValue(pos, value));
}
public static int maxValue(long[] pos, long[] value){
int sum=0;
BigInteger maxSum = BigInteger.valueOf(0);
HashMap<Long,Long> map = new HashMap();
for (int i = 0; i < pos.length; i++) {
if (map.containsKey(pos[i])){
map.put(pos[i],map.get(pos[i])+ value[i]);
}else {
map.put(pos[i],value[i]);
}
}
BigInteger[] dp = new BigInteger[pos.length];
for (int i = 0; i < dp.length; i++) {
dp[i] = countValue(pos[i],map);
maxSum = dp[i].compareTo(maxSum)>0?dp[i]:maxSum;
}
return maxSum.intValue();
}
public static BigInteger countValue(long aim, HashMap<Long,Long> map){
LinkedList<Long> list = new LinkedList();
while (aim!=1){
list.add(aim);
aim = aim/2;//加入目标节点及其父节点
}
list.add(1L);
BigInteger maxV = BigInteger.valueOf(0);
for (Long room:list) {
if (map.containsKey(room)){
maxV = maxV.add(BigInteger.valueOf(map.get(room)));
}
}
return maxV;
}
}