题目一、魔法币

Description

小易准备去魔法王国采购魔法神器,购买魔法神器需要使用魔法币,但是小易现在一枚魔法币都没有,但是小易有两台魔法机器可以通过投入x(x可以为0)个魔法币产生更多的魔法币。
魔法机器1:如果投入x个魔法币,魔法机器会将其变为2x+1个魔法币
魔法机器2:如果投入x个魔法币,魔法机器会将其变为2x+2个魔法币
小易采购魔法神器总共需要n个魔法币,所以小易只能通过两台魔法机器产生恰好n个魔法币,小易需要你帮他设计一个投入方案使他最后恰好拥有n个魔法币。

Input

输入包括一行,包括一个正整数n(1 ≤ n ≤ 10^9),表示小易需要的魔法币数量。

Output

输出一个字符串,每个字符表示该次小易选取投入的魔法机器。其中只包含字符'1'和'2'。

Sample Input

10

Sample Output

122


解题思路

根据题意容易得出公式:f(x)=2x+c,c=1 or 2,经过几次变换恰好得到n,所以反向直接递归出来。

代码

import java.util.Scanner;

public class WangYi1 {
    static int n;
    static void machine(int a){
        if(a<=0) return;
        
            if(a%2!=0){
                machine((a-1)/2);
                System.out.print("1");
            }
            else{
                machine((a-2)/2);
                System.out.print("2");
            }            
    }    
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        sc.close();
        machine(n);        
    }

}

题目二、相反数

Description

为了得到一个数的"相反数",我们将这个数的数字顺序颠倒,然后再加上原先的数得到"相反数"。例如,为了得到1325的"相反数",首先我们将该数的数字顺序颠倒,我们得到5231,之后再加上原先的数,我们得到5231+1325=6556.如果颠倒之后的数字有前缀零,前缀零将会被忽略。例如n = 100, 颠倒之后是1.

Input

输入包括一个整数n,(1 ≤ n ≤ 10^5)

Output

输出一个整数,表示n的相反数

Sample Input

1325

Sample Output

6556


解题思路

将输入的数字转换成字符串放入数组中,然后反向输出字符串,再将反向的字符串转化成数字

代码

import java.util.Scanner;

public class WangYi2 {
    
    static int reverse(String s){
        int l = s.length();
        char[] x = new char[l];
        for(int i=0;i<l;i++){
            x[i] = s.charAt(l-i-1);
        } 
        String ss = new String(x);//将字符数组转化成字符串
        return Integer.parseInt(ss);
        
        
    }
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n;
        n = sc.nextInt();
        sc.close();
        String n1 = String.valueOf(n);
        System.out.print(n+reverse(n1));
    }
    
    

}

题目三、字符串碎片

Description

一个由小写字母组成的字符串可以看成一些同一字母的最大碎片组成的。例如,"aaabbaaac"是由下面碎片组成的:'aaa','bb','c'。×××现在给定一个字符串,请你帮助计算这个字符串的所有碎片的平均长度是多少。

Input

输入包括一个字符串s,字符串s的长度length(1 ≤ length ≤ 50),s只含小写字母('a'-'z')

Output

输出一个整数,表示所有碎片的平均长度,四舍五入保留两位小数。

如样例所示: s = "aaabbaaac"
所有碎片的平均长度 = (3 + 2 + 3 + 1) / 4 = 2.25

Sample Input

aaabbaaac

Sample Output

2.25


解题思路

首先所有块的总长度就是字符串长度,只需要数一下有多少块,再将平均长度四舍五入输出即可


代码

import java.math.BigDecimal;
import java.util.Scanner;

public class WangYi3 {
    
    static public int devide(String s){
        int l = s.length();
        int part = 0;
        char[] s1 = new char[l+1];
        for(int i=1;i<=l;i++){
            s1[i] = s.charAt(i-1);
        }
        for(int i=0;i<l;i++){
            if(s1[i]==s1[i+1]) ;
            else{
                part++;
            }
        }
        return part;
    }
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String st;
        st = sc.next();
        sc.close();
        devide(st);
        double res = st.length()/(double)devide(st);
        //四舍五入保留两位小数
        BigDecimal bd = new BigDecimal(res);
        System.out.print(bd.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        //另一种四舍五入
        System.out.print(String.format("%.2f", res));
    }
}

题目四、游历魔法王国

Description

魔法王国一共有n个城市,编号为0~n-1号,n个城市之间的道路连接起来恰好构成一棵树。
小易现在在0号城市,每次行动小易会从当前所在的城市走到与其相邻的一个城市,小易最多能行动L次。
如果小易到达过某个城市就视为小易游历过这个城市了,小易现在要制定好的旅游计划使他能游历最多的城市,请你帮他计算一下他最多能游历过多少个城市(注意0号城市已经游历了,游历过的城市不重复计算)。

Input

输入包括两行,第一行包括两个正整数n(2 ≤ n ≤ 50)和L(1 ≤ L ≤ 100),表示城市个数和小易能行动的次数。
第二行包括n-1个整数parenti, 对于每个合法的i(0 ≤ i ≤ n - 2),在(i+1)号城市和parent[i]间有一条道路连接。

Output

输出一个整数,表示小易最多能游历的城市数量。

Sample Input

5 2
0 1 2 3

Sample Output

3


解题思路

   贪心算法,寻找图中的最长路径mx,如果小易可以行动的次数L<mx,则显然可以游历的王国数为L+1;如果小易可以行动的次数L>mx,则小易在游历完这条最长路径后需要往回走,但是这样会出现一种状况:假如最长的路径上没有其他分支,分支都连接在根节点上,这样的话整条最长链都要回走,代价太大。所以当我们直到L>mx时,就先把L-mx的次数用在代价小的节点上,因为需要来回,所以游历到的王国个数为:(L-mx)/2+1,最后在加上最长路径上的节点个数即可


代码

import java.util.Scanner;
public class WangYi4{
    public static void main(String[] args){
        Scanner sc  = new Scanner(System.in);
        int n ,L;
        int mx = 0;
        n = sc.nextInt();
        L = sc.nextInt();
        int[] c = new int[n];
        int[] dp = new int[200];
        for(int i=0;i<n-1;i++){
            c[i] = sc.nextInt();
        }
        //寻找最长路径
        for(int i=0;i<n-1;i++){
            dp[i+1] = dp[c[i]]+1;
            mx = Math.max(dp[i+1],mx);
        }
        int d = Math.min(L, mx);
        sc.close();
        System.out.print(Math.min(n, (1+d+(L-d)/2)));
    }
}