目录
一、编程题
1.猴子分桃
2.反转部分单向链表
二、选择题
1.如果希望监听 TCO 端口 9000,服务器端应该怎样创建 socket?
2. jre 判断程序是否执行结束的标准是( )
一、编程题
1.猴子分桃
链接:猴子分桃__牛客网 (nowcoder.com)
老猴子辛苦了一辈子,给那群小猴子们留下了一笔巨大的财富——一大堆桃子。老猴子决定把这些桃子分给小猴子。
第一个猴子来了,它把桃子分成五堆,五堆一样多,但还多出一个。它把剩下的一个留给老猴子,自己拿走其中的一堆。
第二个猴子来了,它把桃子分成五堆,五堆一样多,但又多出一个。它把多出的一个留给老猴子,自己拿走其中的一堆。
后来的小猴子都如此照办。最后剩下的桃子全部留给老猴子。
这里有n只小猴子,请你写个程序计算一下在开始时至少有多少个桃子,以及最后老猴子最少能得到几个桃子。
输入描述:输入包括多组测试数据。 每组测试数据包括一个整数n(1≤n≤20)。 输入以0结束,该行不做处理。
输出描述:每组测试数据对应一行输出。 包括两个整数a,b。 分别代表开始时最小需要的桃子数,和结束后老猴子最少能得到的桃子数。
示例1
输入
5
1
0
输出
3121 1025
1 1
🔎做题思路:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int n = scanner.nextInt();
if (n == 0) {
break;
} else {
long startMin =(long) Math.pow(5, n) - 4;//每次分5个剩一个,借4个就可以全分完
//分1次-----------剩(x+4)*(4/5)
//分2次-----------剩(x+4)*(4/5)^2
//分完n次, 剩(x+4)*(4/5)^n
//剩的数目为整数,且最小,则:(x+4)=5^n,即剩 4^n
//老猴子得到的数目:剩(4^n)+n(猴子数)-4(借4个)
long endMin = (long) Math.pow(4, n) + n - 4;
System.out.println(startMin + " " + endMin);
}
}
}
2.反转部分单向链表
链接:反转部分单向链表__牛客网 (nowcoder.com)
给定一个单链表,在链表中把第 L 个节点到第 R 个节点这一部分进行反转。
输入描述: n 表示单链表的长度。 val 表示单链表各个节点的值。 L 表示翻转区间的左端点。 R 表示翻转区间的右端点。
输出描述: 在给定的函数中返回指定链表的头指针。
示例1
输入
5
1 2 3 4 5
1 3
输出
3 2 1 4 5
做题思路:
public class Main {
//首先定义单链表的节点
static class Node {
int val;
Node next;
public Node(int val) {
this.val = val;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//获取当前链表的节点个数
int n = scanner.nextInt();
//吃掉 nextInt 方法的换行符
scanner.nextLine();
//"1 2 3 4 5"
String nodeValue = scanner.nextLine();
String[] nodes = nodeValue.split(" ");//按照空格拆分
//1.进行单链表的创建
Node dummyHead = new Node(-1);//虚拟节点
Node tail = dummyHead;
for (int i = 0; i < n; i++) {
//链表的尾插
Node node = new Node(Integer.parseInt(nodes[i]));//字符串转化为整型
tail.next = node;
tail = node;
}
//2.获取左区间和右区间的范围“1 3”
String part = scanner.nextLine();
// 1
int left = Integer.parseInt(part.split(" ")[0]);//空格拆分第一个是左区间
// 3
int right = Integer.parseInt(part.split(" ")[1]);//空格拆分第二个是右区间
//将传入链表按照左区间到右区间进行翻转
Node newHead = reversePartList(dummyHead.next, left, right);
//进行输出处理
while (newHead != null) {
System.out.print(newHead.val + " ");
newHead = newHead.next;
}
}
private static Node reversePartList(Node head, int left, int right) {
Node dummyHead = new Node(-1);//虚拟节点
dummyHead.next = head;
// prev 引用指向待反转区间的前驱节点
Node prev = dummyHead;
for (int i = 1; i < left; i++) {
prev = prev.next;
}
//cur 引用就是待反转区间的第一个节点
Node cur = prev.next;
for (int i = left; i < right; i++) {
Node third = cur.next;
//先把 third 引用从链表中删除
cur.next = third.next;
//再把 third 节点头插入 prev 之后
third.next = prev.next;
prev.next = third;
}
return dummyHead.next;
}
}