10.第八届蓝桥杯
4 小数第n位
import java.util.Scanner;
public class 小数第n位 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
int n = scanner.nextInt();
// 算出结果
double ans = 1.0*a/b;
String ss = ans+"";
// 取出小数部分
ss = ss.substring(ss.indexOf('.')+1);
// 如果n的值大于大数部分的长度,直接输出000
if (ss.length()<n) {
System.out.println("000");
return;
}
// 若果小数部分的值小于n+2这个范围,补个0
if (ss.length()<n+2) {
for (int i = 0; i <2; i++) {
ss+="0";
}
}
// 截取值
ss = ss.substring(n-1, n+2);
System.out.println(ss);
}
}
分考场
https://blog.csdn.net/qq_41923622/article/details/80405277
https://blog.csdn.net/fuzekun/article/details/85220468
https://blog.csdn.net/Z_H86/article/details/113774130
import java.util.Scanner;
public class 分考场4 {
static int relaChart[][];//relational chart
static int roomChart[][];//考场表
static int n,rooms;//考生人数 考场数
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a,b;
n = scanner.nextInt();
int m = scanner.nextInt();
rooms = n;
relaChart = new int[n+1][n+1];
roomChart = new int[n+1][n+1];
while(m-->0){
a = scanner.nextInt();
b = scanner.nextInt();
// 认识就是1,不认识就是0
relaChart[a][b]=relaChart[b][a]=1;
//建立a和b之间的认识关系
}
DFS(1,1); //从第一个人开始安排教室
}
/**
*
* @param x:第几个人
* @param r:房间数
*/
static void DFS(int x,int r){
int i,j;
if(r>=rooms) return;//剪枝!!
//rooms存的是已经找到的可行方案中最小的考场数
//如果现在的考场数r已经大于了rooms了,那么这个方案肯定是不行的了
// 安排的人已经大于总共的人数,所以剪枝掉
if(x>n){
rooms=Math.min(r, rooms);
return;
}
// 这里的i代表了是第几个考场
for(i=1;i<=r;i++){
// 这里的j代表着的是座位,每次都要初始化一下
j=1; //从每个考场第一个座位开始找
// roomChart[i][j]:代表着的是这个人的编号,
// 再加上x,就可以找到这个人了
// roomChart[i][j] > 0:说明有人了,具体的值代表的是第几个人(编号):
// relaChart[roomChart[i][j]][x]:代表者在座位上的人和正在分配的这个人的关系,
// 0代表不认识,1代表认识
// 如果当前作为有人且不认识,直接去看下一个座位,如果认识,跳出循环,因为他们已经不能在同一个考场上了
// 如果这个座位没人,也跳出循环,把要安排的人放在这里即可
while(roomChart[i][j] > 0 && relaChart[roomChart[i][j]][x]==0)
//如果当前考场第j个座位有人并且两个人之间不认识
j++; //就继续找下一个座位
// 当前这个考场的这个座位没人,就直接往里添加,否则就代表考场上有人认识,就不能再往里添加了
if(roomChart[i][j]==0){
//如果找到一个空位,那个该考生肯定跟前面的人都不认识
// 把这个人安排在这个座位上
roomChart[i][j]=x;
//那么该考生的考场和座位就找到了
// 接下来安屁第x+1个人了,房间数不变
DFS(x+1,r);
// 这个人不行,重新安排
roomChart[i][j]=0;
//回溯!!将x的位置清零,重新给它安排考场
}
}
//如果找完所有考场也没有合适的座位,那么就只有增加一个考场了
roomChart[i][1]=x;
DFS(x+1,r+1);
roomChart[i][0]=0;
// 回溯!!将x的位置清零,并返回到上一层函数,重新给它安排考场
}
}
分析:
1 2 3 4
14;23;34:
relate:
1 0 0 0
0 0 1 0
0 1 0 1
0 0 1 1
room:
横排代表考场,列代表的是座位
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
第一个参数是第几个人,第二个参数是考场数
dfs(1,1):
room:
1 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
dfs(2,1):
room:
1 2 0 0
0 0 0 0
0 0 0 0
0 0 0 0
dfs(3,1):
新加一个考场
room:
1 2 0 0
3 0 0 0
0 0 0 0
0 0 0 0
dfs(4,2):
再添加一个考场
room:
1 2 0 0
3 0 0 0
4 0 0 0
0 0 0 0
dfs(5,3)
合根植物
- 是一个并查集问题
import java.util.Scanner;
public class 分考场3 {
static int[] pre ;
static int ans;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n1 = scanner.nextInt();
int n2 = scanner.nextInt();
int n = n1*n2;
int m = scanner.nextInt();
// 记录每个结点的父节点
pre = new int[n+1];
// 刚开始的时候每个结点的父节点是自己,先初始化一下
for (int i = 1; i <= n; i++) {
pre[i] = i;
}
for (int i = 0; i < m; i++) {
int a = scanner.nextInt();
int b = scanner.nextInt();
int fa = find2(a);
int fb = find2(b);
// 合并父节点,就是把第二个赋给第一个
if (fa != fb) {
pre[fb] = fa;
}
}
for (int i = 1; i <= n; i++) {
// 等下标和元素值相等时,代表它是一个集合
if (pre[i] ==i ) {
ans++;
System.out.print(i+":"+pre[i]+"\t");
}
System.out.print(i+":"+pre[i]+"\t");
}
}
private static int find(int x) {
// 查找这个人(a)的父节点,数组的下标就代表这个人
// 当下标等于元素值时,就找了父节点
while (pre[x] != x) {
// pre[x]:x这个人的父节点,这样就可以一直循环,直到找到父节点
x = pre[x];
}
return x;
}
// 这是经过压缩的算法
private static int find2(int x) {
// 查找这个人(a)的父节点,数组的下标就代表这个人
// 当下标等于元素值时,就找了父节点,最终可以找到集合结点
int temx = x;
while (pre[x] != x) {
// pre[x]:x这个人的父节点,这样就可以一直循环,直到找到父节点
x = pre[x];
}
// // 压缩路径
int temp;
// 当前结点不是父节点的时候,就一直开始遍历
while (temx != x) {
// 获取节点的父节点
temp = pre[temx];
// 把当前结点的父节点设为集合节点
pre[temx]= x;
// 把父节点赋给当前结点,进行跟新
temx = temp;
}
return x;
}
}