day28—编程题

文章目录

  • 1.第一题
    • 1.1题目
    • 1.2涉及的相关知识
    • 1.3思路
    • 1.4解题
  • 2.第二题
    • 2.1题目
    • 2.2思路
    • 2.3解题

1.第一题

1.1题目

描述:
老猴子辛苦了一辈子,给那群小猴子们留下了一笔巨大的财富——一大堆桃子。老猴子决定把这些桃子分给小猴子。第一个猴子来了,它把桃子分成五堆,五堆一样多,但还多出一个。它把剩下的一个留给老猴子,自己拿走其中的一堆。第二个猴子来了,它把桃子分成五堆,五堆一样多,但又多出一个。它把多出的一个留给老猴子,自己拿走其中的一堆。后来的小猴子都如此照办。最后剩下的桃子全部留给老猴子。这里有n只小猴子,请你写个程序计算一下在开始时至少有多少个桃子,以及最后老猴子最少能得到几个桃子。
输入描述:
输入包括多组测试数据。
每组测试数据包括一个整数n(1≤n≤20)。
输入以0结束,该行不做处理。
输出描述:
每组测试数据对应一行输出。
包括两个整数a,b。
分别代表开始时最小需要的桃子数,和结束后老猴子最少能得到的桃子数。

1.2涉及的相关知识

pow() 方法用于返回第一个参数的第二个参数次方
语法:double pow(double base, double exponent)
参数:base – 任何原生数据类型;exponent – 任何原生数据类型
返回值:返回第一个参数的第二个参数次方

1.3思路

  1. 因为每次分5堆都会多出来1个,所以我们借给猴子们4个,以致每次都可以刚好分成5堆 并且,每次给老猴子的桃子都不在我们借出的那4个中,这样最后减掉4就可以得到结果
  2. 假设最初有x个桃子,我们借给猴子4个,则此时最初有x+4个桃子, 第一个猴子得到(x+4)/ 5,剩余(x+4)/(4/5)个,第二个猴子分完后剩余(x+4)/ (4/5) ^ 2个,第三个猴子分完后剩余(x+4)/(4/5) ^ 3个,依次类推,第n个猴子分完后剩余(x+4)/(4/5)^ n
  3. 要满足最后剩余的为整数,并且x最小,则当 x+4=5 ^ n时,满足要求;此时,x=5 ^ n - 4;;老猴子得到的数量为:(x+4)*(4/5)^ n + n - 4 = 4 ^ n + n - 4,最后的 +n是因为每个小猴子都会多出一个给老猴子,-4是还了借的4个

1.4解题

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n;
        while ((n = sc.nextInt()) != 0 ) {
            long a = (long)(Math.pow(5,n) - 4);//桃子的总数
            long b = (long)(Math.pow(4,n) + n - 4);//老猴子拿到桃子的数量
            System.out.println(a + " " + b);
        }
        
    }
}

2.第二题

2.1题目

描述:
给定一个单链表,在链表中把第 L 个节点到第 R 个节点这一部分进行反转。
输入描述:
n 表示单链表的长度。
val 表示单链表各个节点的值。
L 表示翻转区间的左端点。
R 表示翻转区间的右端点。
输出描述:
在给定的函数中返回指定链表的头指针

2.2思路

  1. 反转链表:定义一个虚拟节点让他指向头结点,找到要反转链表的前一个节点,依次反转当前结点和下一个节点(先把要反转的下一个节点从链表中删除,再将这个结点头插入要反转的前一个节点的下一个节点)
  2. 创建链表是注意引入虚拟节点

2.3解题

import java.util.Scanner;
//定义结点
class Node {
    int val;
    Node next;
    public Node() {}
    public Node(int val) {
        this.val = val;
    }
}
public class Main {
    //链表翻转
    public static Node reverse(Node head, int left, int right) {
        if (head == null) {
            return null;
        }
        Node node = new Node(-1);//定义一个虚拟节点让他指向头结点
        node.next = head;
        Node pre = node;
        //找到要反转链表的前一个节点
        for (int i = 0; i < left - 1; i++) {
            pre = pre.next;
        }
        Node cur = pre.next;//指向要反转的第一个结点
        //依次反转当前结点和下一个节点
        for (int i = 0; i < right - left; i++) {
            Node curNext = cur.next;
            //先把要反转的下一个节点从链表中删除
            cur.next = curNext.next;
            //再将这个结点头插入pre的下一个节点
            curNext.next = pre.next;
            pre.next = curNext;
        }
        //返回头结点
        return node.next;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] array = new int[n];
        Node headPrev = new Node();//虚拟节点
        Node tmp = headPrev;
        //创建链表
        for (int i = 0; i < n; i++) {
            array[i] = sc.nextInt();
            Node node = new Node(array[i]);
            tmp.next = node;
            tmp = node;
        }
        int left = sc.nextInt();
        int right = sc.nextInt();
        Node newNode = reverse(headPrev.next, left, right);
        //打印反转后的链表
        while (newNode != null) {
            System.out.print(newNode.val + " ");
            newNode = newNode.next;
        }
    }
}

你可能感兴趣的:(每日一题,数据结构,算法,java)