879. 幸存者游戏
约瑟夫环的模拟问题
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
boolean[] isDelete = new boolean[n + 1]; //记录当前位置上的人是否已经出圈
int start = 1; //记录计数开始的起点,left表示还剩下多少人
for (int i = 1, left = n; i <= n; i++, left--) {
int k = 1;
for (int j = 1; j <= i; j++)
k = k * m % left;
if (k == 0)
k = left;
while (true) {
if (!isDelete[start]) {
k--;
if (k == 0) {
isDelete[start] = true;
break;
}
}
start++;
if (start > n)
start = 1;
}
}
System.out.println(start);
}
}
880. 数字对生成树
广度优先搜索算法,需要明确的是
1.只有一个根节点
2.从根节点可以遍历到其他所有节点
3.除了根节点之外所有节点有且只有一个父节点
import java.util.*;
public class Main {
public static HashMap<Integer, HashSet<Integer>> adjlist; //邻接表
public static HashMap<Integer, Integer> distToRoot, timeStamp; //记录节点到根节点的距离,节点的第一次时间戳
public static HashSet<Integer> hasFather; //记录具有父节点的节点编号
static class Node implements Comparable<Node> {
int id, dist, timestamp;
public Node(int id, int dist, int timestamp) {
this.id = id;
this.dist = dist;
this.timestamp = timestamp;
}
@Override
public int compareTo(Node o) {
int delta = this.dist - o.dist;
return delta == 0 ? this.timestamp - o.timestamp : delta;
}
}
public static ArrayList<Node> bfs(int root){
ArrayList<Node> ans=new ArrayList<>();
Queue<Node> que=new LinkedList<>();
que.add(new Node(root,distToRoot.get(root),timeStamp.get(root)));
while (!que.isEmpty()){
Node tmp=que.poll();
ans.add(tmp);
if(!adjlist.containsKey(tmp.id))
continue;
for(int i:adjlist.get(tmp.id)){
if(distToRoot.containsKey(i))
return new ArrayList<>();
else
{
distToRoot.put(i,tmp.dist+1);
Node node=new Node(i,tmp.dist+1,timeStamp.get(i));
que.add(node);
}
}
}
Collections.sort(ans);
return ans;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
hasFather = new HashSet<>();
distToRoot = new HashMap<>();
timeStamp = new HashMap<>();
adjlist = new HashMap<>();
int n = in.nextInt();
int time = 0;
while (n > 0) {
String[] q=in.next().split(",");
int a = Integer.valueOf(q[0]);
int b = Integer.valueOf(q[1]);
n--;
if (adjlist.containsKey(a) && adjlist.get(a).contains(b))
continue;
else {
HashSet tmp = adjlist.getOrDefault(a, new HashSet<>());
tmp.add(b);
adjlist.put(a,tmp);
if(!timeStamp.containsKey(a))
timeStamp.put(a, time++);
if(!timeStamp.containsKey(b))
timeStamp.put(b,time++);
hasFather.add(b);
}
}
int root = -1, cnt = 0;
for (int i : timeStamp.keySet()) {
if (!hasFather.contains(i)) {
root = i;
cnt++;
}
}
if (root == -1 || cnt > 1) {
System.out.println("Not a tree");
return;
}
distToRoot.put(root, 0);
ArrayList<Node> arr=bfs(root);
if(arr.size()<timeStamp.size())
{
System.out.println("Not a tree");
return;
}else {
System.out.print(arr.get(0).id);
for(int i=1;i<arr.size();i++)
{
System.out.print(","+arr.get(i).id);
}
}
}
}
881. 整理书架
根据N和k的范围可以使用暴力解法来求逆序对而不需要用更高效的归并算法
import java.util.*;
public class Main {
static class Record implements Comparable<Record> {
int index;
int num;
public Record(int index, int num) {
this.index = index;
this.num = num;
}
@Override
public int compareTo(Record o) {
return this.num - o.num;
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int k = in.nextInt();
Record[] records = new Record[N];
int[][] bookNo = new int[N][k];
for (int i = 0; i < N; i++) {
for (int j = 0; j < k; j++) {
bookNo[i][j] = in.nextInt();
}
int cnt = 0;
for (int m = 0; m < k - 1; m++) {
for (int n = m + 1; n < k; n++) {
if (bookNo[i][m] > bookNo[i][n])
cnt++;
}
}
records[i] = new Record(i, cnt);
}
Arrays.sort(records);
System.out.print("[");
for(int i=0;i<N;i++){
int[] tmp=bookNo[records[i].index];
System.out.print("[");
for(int j=0;j<k;j++){
if(j==0){
System.out.print(tmp[j]);
continue;
}
System.out.print(", "+tmp[j]);
}
if(i==N-1)
{
System.out.print("]");
continue;
}
System.out.print("], ");
}
System.out.print("]");
}
}
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int K = in.nextInt();
int H = in.nextInt();
int[][] dp = new int[H + 1][K + 1]; //dp[i][j]表示高度范围为1~i,使用j个飞机时在最坏情况下求出最低可俯冲高度的试验次数
for (int i = 1; i <= H; i++) {
dp[i][1] = i;
}
for (int i = 1; i <= K; i++)
dp[1][i] = 1;
for (int i = 2; i <= H; i++) {
for (int j = 2; j <= K; j++) {
dp[i][j] = dp[i][j - 1];
for (int k = 1; k <= i; k++) {
dp[i][j] = Math.min(dp[i][j], 1 + Math.max(dp[k - 1][j - 1], dp[i - k][j]));
}
}
}
System.out.print(dp[H][K]);
}
}