Day 28 反转部分单向链表+猴子分桃

目录

 1.反转部分单向链表

 2.猴子分桃


 1.反转部分单向链表

链接:反转部分单向链表__牛客网
来源:牛客网
 

[编程题]反转部分单向链表

  • 热度指数:2164 时间限制:C/C++ 4秒,其他语言8秒 空间限制:C/C++ 256M,其他语言512M

给定一个单链表,在链表中把第 L 个节点到第 R 个节点这一部分进行反转。

输入描述:

n 表示单链表的长度。

val 表示单链表各个节点的值。

L 表示翻转区间的左端点。

R 表示翻转区间的右端点。


 

输出描述:

在给定的函数中返回指定链表的头指针。

示例1

输入

5
1 2 3 4 5
1 3

输出

3 2 1 4 5

注意1.  sc.nextLine();

2.字符串反转时候 

import java.util.*;

public class Main{
    public static void main(String[] args){
       Scanner sc = new Scanner(System.in);
       int n = sc.nextInt();
        // 吃掉nextInt的换行符
        sc.nextLine();

        String str = sc.nextLine();
       int left = sc.nextInt();
       int right = sc.nextInt();
       String[] arr = str.split(" ");
       Node dummyHead = new Node();
       Node head = dummyHead;
        for (int i = 0; i < n; i++) {
            Node node = new Node(Integer.parseInt(arr[i]));
            head.next = node;
            head = node;
        }
        Node newNode = reversePartList(dummyHead.next,left,right);
        while (newNode != null){
            System.out.print(newNode.val+" ");
            newNode = newNode.next;
        }
    }
    public static Node reversePartList(Node head, int left, int right) {
        Node dummyHead = new Node();
        dummyHead.next = head;
        Node prev = dummyHead;
        for (int i = 1; i < left; i++) {
            prev = prev.next;
        }
        // prev指向待反转的区间前驱,cur指向待反转的第一个节点
        Node cur = prev.next;
        for (int i = 0; i < (right-left); i++) {
            Node tmp = cur.next;
            // 先把next从链表中删除
            cur.next = tmp.next;
            // 再将next头插cur之前
            tmp.next = prev.next;
            prev.next = tmp;

        }
        return dummyHead.next;
    }
}
class Node{
    int val;
    Node next;
    public Node(){
    }
    public Node(int val){
        this.val = val;
    }
}

2.猴子分桃

链接:猴子分桃__牛客网
来源:牛客网
 

[编程题]猴子分桃

  • 热度指数:2412 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M

老猴子辛苦了一辈子,给那群小猴子们留下了一笔巨大的财富——一大堆桃子。老猴子决定把这些桃子分给小猴子。
第一个猴子来了,它把桃子分成五堆,五堆一样多,但还多出一个。它把剩下的一个留给老猴子,自己拿走其中的一堆。
第二个猴子来了,它把桃子分成五堆,五堆一样多,但又多出一个。它把多出的一个留给老猴子,自己拿走其中的一堆。
后来的小猴子都如此照办。最后剩下的桃子全部留给老猴子。
这里有n只小猴子,请你写个程序计算一下在开始时至少有多少个桃子,以及最后老猴子最少能得到几个桃子。

输入描述:

输入包括多组测试数据。
每组测试数据包括一个整数n(1≤n≤20)。
输入以0结束,该行不做处理。


 

输出描述:

每组测试数据对应一行输出。
包括两个整数a,b。
分别代表开始时最小需要的桃子数,和结束后老猴子最少能得到的桃子数。

示例1

输入

5
1
0

输出

3121 1025
1 1

 开始时的总桃子数X = 5^n - 4
 老猴子最后能得到的桃子数n + (X+4)*(4/5)^n - 4 = n + 4^n - 4

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()){
            int n = sc.nextInt();
            if(n==0) break;
            long a = (long) (Math.pow(5, n) - 4);
            long b = (long) (Math.pow(4, n) + n - 4);
            System.out.println(a + " " + b);
        }
    }
}

猴子分桃问题描述如下:五只猴子在海边捡到了一堆桃子,它们决定分掉这堆桃子,但是它们发现它们太累了,于是决定先休息一会儿,等到第二天再分。于是这五只猴子开始分,第一只猴子把桃子分成了五堆,每堆多一个;第二只猴子把剩下的桃子分成了五堆,每堆多一个;然后第三只、第四只、第五只猴子都按照同样的方法分桃。最后发现桃子刚好分完,问这堆桃子最少有多少个? 我们可以利用单循环链表来解决这个问题。具体思路如下: 1. 最后一个猴子分完桃子后,剩下的桃子数量为 1。 2. 第五只猴子得到的桃子数量为 `(4 * 上一只猴子得到的桃子数量 + 1)`,即 `4x + 1`。 3. 根据上面的公式,倒推出第四只猴子得到的桃子数量,为 `(5x + 1) / 4`。 4. 继续倒推,可以得到第三只猴子得到的桃子数量为 `(25x + 6) / 20`,第二只猴子得到的桃子数量为 `(125x + 31) / 100`,第一只猴子得到的桃子数量为 `(625x + 156) / 500`。 5. 然后我们可以通过一个 while 循环,不断地将剩下的桃子数量分成五份,每份多一个,直到最后剩下的桃子数量为 1,这样就可以求出这堆桃子最少有多少个。 下面是利用单循环链表结构实现的 Python 代码: ```python class Node: def __init__(self, data): self.data = data self.next = None def monkey_divide_peach(): last_node = Node(1) for i in range(4): current_node = Node((last_node.data * 5 + 1) // 4) current_node.next = last_node last_node = current_node peach_num = last_node.data current_node = last_node while current_node.next: peach_num = peach_num * 5 + 1 current_node = current_node.next while peach_num % 4 != 0: peach_num += 5 ** 5 return peach_num print(monkey_divide_peach()) # 输出:3121 ``` 在上面的代码中,我们首先根据猴子分桃的规律,用单向链表倒推出最后一只猴子得到的桃子数量,然后通过一个 while 循环,不断地将剩下的桃子数量分成五份,每份多一个,直到最后剩下的桃子数量为 1,这样就可以求出这堆桃子最少有多少个。最后输出结果为 3121。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习java的张三

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值