28. ①反转部分单向链表(数据结构) ②猴子分桃(数学关系)

目录

①反转部分单向链表

②猴子分桃


①反转部分单向链表

 

import java.util.*;
public class demo1 {
    //首先通过内部类定义链表的节点
    static  class Node{
        int val;
        Node next;
        public Node(int val){
            this.val=val;
        }
    }
    public static void main(String[] args) {
        //链表的每个节点的值在一行输入结束了,每个节点的
        //值用空格分隔。就需要使用nextline一次读取一行的输入
        //得到一个节点值的字符串"1 2 3 4 5"
        Scanner scanner=new Scanner(System.in);
        //获取当前链表的节点个数
        int n=scanner.nextInt();
        //从nextInt获取一个节点值后,使用回车键结束本次输入,\n就会被
        //nextLine方法所捕获
        //因而通过nextLine吃掉nextInt的换行符
        scanner.nextLine();
        //“1 2 3 4 5”
        String nodevalue=scanner.nextLine();
        String[] nodes=nodevalue.split(" ");
        //进行链表的创建
        //创建一个虚拟节点
        Node dummyHead=new Node(-1);
        Node tail=dummyHead;
        for (int i=0; i<n;i++){
            //链表的尾插
            Node node=new Node(Integer.parseInt(nodes[i]));
            //将输入的节点依次插入到tail后面
            tail.next=node;
            tail=node;
        }
        //获取左区间和右区间的范围
        //nextLine遇到空格就读取然后结束了,因而不会像next()一样
        //产生空格导致读取到空
        String part=scanner.nextLine();
        int left=Integer.parseInt(part.split(" ")[0]);
        int right=Integer.parseInt(part.split(" ")[1]);
        //开始执行实现反转的函数
        Node newHead=reversePartList(dummyHead.next,left,right);
        //进行输出处理
        while (newHead!=null){
            System.out.println(newHead.val+" ");
            newHead=newHead.next;
        }
    }
    public 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节点走left-1次
            prev=prev.next;
        }
        //prev引用指向待反转区间的前驱节点,cur引用就是待反转区间的第一个节点
        Node cur=prev.next;
        for (int i = left; i < right; i++) {
            //third表示第一个被删除节点的next节点
            Node third=cur.next;
            //把third引用从链表删除
            cur.next=third.next;
            //再把third节点头插入prev之后
            third.next=prev.next;
            prev.next=third;
        }
        return dummyHead.next;
    }
}

②猴子分桃

import java.util.*;
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;
            }
            //主要考察的是数学关系式,假设n个猴子每次分桃时有Xi个桃子
            //根据题目描述,每次分五堆会剩余一个桃子,因而可以在最开始先借四个桃子
            //补在其中剩余的四堆里面,每次分完的桃子都在下一次要分的桃子中
            //那么可以
            //那么,每次都可以平分桃子xi+4个
            //例如第一次分桃则是拿走(x1+4)/5,剩余(x1+4)*4/5个桃子
            //第二次分则是拿走(x1+4)*4/5  /5,剩余(x1+4)*4/5*4/5
            //第N次分则是拿走(x1+4)*(4/5)^n
            //为满足题目要求,剩余桃子数量应为整数,且最开始桃子数量X1
            //要最小,因而X1+4=5^n因而X1=5^n-4,即最开始的桃子数量至少为
            //5^n-4
            //老猴子分的的桃子数量:当X1最小时可求得n次均分后剩余4^n个,加上n个
            //猴子每次分完给他的n个,减去借的四个,为4^n+n-4
            //***************************
            //这里小猴子获得的桃子包含了给老猴子的一个,因而小猴子没有多拿
            //借的四个一直都在剩余那一堆里,一直能够均分为5堆
                long a=(long)(Math.pow(5,n)-4);
                long b=(long)(Math.pow(4,n)+n-4);
                System.out.println(a+" "+b);
            }
        }
    }

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
猴子分桃问题描述如下:五只猴子在海边捡到了一堆桃子,它们决定分掉这堆桃子,但是它们发现它们太累了,于是决定先休息一会儿,等到第二天再分。于是这五只猴子开始分,第一只猴子把桃子分成了五堆,每堆多一个;第二只猴子把剩下的桃子分成了五堆,每堆多一个;然后第三只、第四只、第五只猴子都按照同样的方法分桃。最后发现桃子刚好分完,问这堆桃子最少有多少个? 我们可以利用单循环链表来解决这个问题。具体思路如下: 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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值