9.第9届蓝桥杯
https://blog.csdn.net/qq_43449564/article/details/109333799
https://blog.csdn.net/weixin_44034328/article/details/105332551
https://blog.csdn.net/weixin_43771695/article/details/104131313
2 海盗与金币
https://blog.csdn.net/bettle_king/article/details/115802052
import java.util.Arrays;
public class 海盗与金币 {
public static void main(String[] args) {
int[] gold = new int[12];
// 第12轮所有人都相等的金币数d
Arrays.fill(gold, 4096);
// 12个海盗,开始逆推:每个海盗都分出自己财产的1/2,给一个海盗,执行12次
for (int i = 0; i < 12; i++) {
int sum = 0;
// 其他海盗补偿给当前海盗
for (int j = 0; j < 12; j++) {
// 自己不分给自己
if (i == j) continue;
// 其他海盗财产折半
gold[j] /= 2;
// 折半的财产相加
sum += gold[j];
}
// 赋给当前海盗
gold[i] += sum;
}
for (int i = 0; i < gold.length; i++) {
System.out.print(gold[i]+" ");
}
}
}
- 优化
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] coin = new int[12];
for (int sum = 12; sum <= 50000; sum+= 12) {
Arrays.fill(coin, sum / 12);
// 反向遍历
dfs(0, sum, coin);
}
}
static void dfs(int cur, int sum, int[] coin) {
// 到了第2个海盗
if (cur == 12) {
for (int i = 0; i < 12; i++)
System.out.print(coin[i] + " ");
System.out.println();
} else {
int cnt = 0;
for (int i = 0; i < 12; i++) {
// 自己不分给自己
if (i == cur) continue;
// 金币不能折半的去掉
if (coin[i]%2 != 0) return;
// 金币的折半
cnt += coin[i] /= 2;
}
// 分给当前的海盗
coin[cur] += cnt;
dfs(cur + 1, sum, coin);
}
}
}
4 约瑟夫环
- 数组
import java.util.Scanner;
public class Test3 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int k = scanner.nextInt();
boolean[] arr = new boolean[n];
int tem = 0;
int kk = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == false) {
// 当这点还存在时,进行相加
kk++;
}
if (kk == k) {
arr[i] = true;
tem++;
// 把这个值重置,然后就可以重新判断了
kk = 0;
}
// 判断是否只剩下了最后一个
if (tem == arr.length-1) {
for (int j = 0; j < arr.length; j++) {
if (arr[j] == false) {
System.out.println(j+1);
break;
}
}
// 跳出外层循环
break;
}
if (i == arr.length-1) {
// 重新遍历
i = -1;
}
}
}
}
- 链表
import java.util.Scanner;
public class Test2 {
static class Node{
// 记录当前节点的坐标
int position;
// 它的下一个节点
Node next;
public Node(int position) {
super();
this.position = position;
}
public Node() {
super();
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int k = scanner.nextInt();
// 前后辅助节点和头结点
Node PreNode = new Node();
Node AfterNode = new Node();
Node headNode = new Node(0);
AfterNode = headNode;
// 从第二个结点开始遍历
for (int i = 1; i < n; i++) {
// 当前节点赋给前节点
PreNode = AfterNode;
Node node = new Node(i);
// 当前节点的赋值
AfterNode = node;
// 前节点连接当前节点
PreNode.next = AfterNode;
}
// 末尾节点指向头结点
AfterNode.next = headNode;
// 重置两个辅助节点,都指向头结点
PreNode = headNode;
AfterNode = headNode;
// tem:代表个数,kk代表书否到了k值
int kk = 1,tem = 0;
while (true) {
// 这里的kk代表了AfterNode所在的位置,因为AferNode会在其实的位置+1,所以k要从1开始
// PreNode代表当前节点
kk++;
// 保留当前的结点
PreNode =AfterNode;
// AfterNode指向当前节点的下一个节点
AfterNode = AfterNode.next;
// 如果kk已经到了k
if (kk == k) {
// 直接去掉,当前节点直接指向下一个节点(目标)的下一个节点,实现了删除功能
PreNode.next = AfterNode.next;
// 把当前节点赋值AfterNode,然后循环之后在赋给PreNode,这样就代表了起始节点
AfterNode = PreNode.next;
// 重置kk的值
kk = 1;
// 记录个数
tem++;
}
if (tem == n-1) {
System.out.println(PreNode.position+1);
break;
}
}
}
}
- 公式
https://blog.csdn.net/u011500062/article/details/72855826