华为笔试算法题解

华为笔试算法题解

第1题 字符串处理

思路:先过滤掉数字,然后按GBK编码扫描汉字的长度,若为偶则子串长度length-cnt/2,若为奇则子串长度length-(cnt/2+1)(GBK编码汉字为2字节,数值小于0)

import java.io.UnsupportedEncodingException;
import java.util.Scanner;

/**
 * 
 * 在GBK编码下,请编写一个截取字符串的函数, 输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字不被截半个,
 * 同时忽略字符串中的数字后输出最终结果。
 *
 * 输入描述:
 *
 *     一行字符串和待截取的字节数
 *
 * 输出描述:
 *
 *     单独的一行截取后的字符串
 *
 * 示例1
 *
 * 输入
 *
 *     华HUA
 *     4
 *
 * 输出
 *
 *     华HU
 *
 * 备注:
 *
 *     要保证汉字不被截半个,同时忽略字符串中的数字后输出最终结果。
 */
public class Str {
    static String splitString(String str,int length){
        try {
            byte[] bytes = str.getBytes("GBK");
            int cnt=0;
            for(byte x:bytes){
                if(x<0) cnt++;
            }
            if(cnt%2==0) return str.substring(0,length-cnt/2);
            else return str.substring(0,length-cnt/2-1);

        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }
        return null;
    }
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        while(scanner.hasNext()){
            String str=scanner.nextLine();
            int length=scanner.nextInt();
            String str1=str.replaceAll("\\d","");
            String ans=splitString(str1,length);
            System.out.println(ans);
        }
        scanner.close();
    }
}

第2题 日期

利用Calendar类处理,注意月份从0开始,星期从周日开始

import java.util.Calendar;
import java.util.Scanner;

/**
 *
 * 13号又恰好是星期五真的很特殊吗?也就是说,13号出现在星期五的几率比出现在其它周日的几率大吗?要回答这个问题,
 *
 * 写一个程序计算13日出现在某个星期的次数(在给定的N年时间中)。这个时间段为1900年1月1日到1900+N-1年12月31日。
 *
 * N为非负整数,不超过400。(1900年1月1日是星期一)
 *
 * 输入描述:
 *
 *     1 0
 *     第一个参数为years,表示距离1900年1月1日的年数
 *     第二个参数为weeks,表示星期数(分别用0——6代表星期日到星期六)
 *
 * 输出描述:
 *
 *     13日出现在星期数为weeks的次数,若异常失败输出-1
 *
 * 示例1
 *
 * 输入
 *
 *     1 0
 *
 * 输出
 *      1
 */
public class Cal {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        while(scanner.hasNext()){
            int years=scanner.nextInt();
            int weeks=scanner.nextInt();
            if(years<=0 || weeks>6 || weeks <0){
                System.out.println("-1");
                continue;
            }

            Calendar calendar=Calendar.getInstance();
            int cnt=0;
            for(int i=1900;i<1900+years;i++)
                for(int j=0;j<12;j++){
                    calendar.set(i,j,13);
                    int week=calendar.get(Calendar.DAY_OF_WEEK)-1;
                    if(week==weeks)
                        cnt++;
                }
            System.out.println(cnt);
        }
        scanner.close();
    }
}

第3题 DP

\(dice[i][j]\)表示i个骰子出现和为j的可能数,即为i-1个骰子扔出的和分别为j-1,j-2...j-6加上第i个骰子扔出1,2...6的情况和,可以写出如下的表达式

\[dice[i][j]=dice[i-1][j-1]+dice[i-1][j-2]+dice[i-1][j-3]+dice[i-1][j-4]+dice[i-1][j-5]+dice[i-1][j-6] \]

注意过滤一下和为负的情况

import java.util.ArrayList;
import java.util.Scanner;

/**
 *
 * 有N个骰子,同时投掷出去,向上面的数字之和为 A。
 *
 * 那么输入为N个筛子,请计算出A,和他出现的概率。
 *
 * 概率值,小数点保留5位。
 *
 * 输入描述:
 *
 *     N,骰子数目
 *
 * 输出描述:
 *
 *     [[1, 0.16667], [2, 0.16667], [3, 0.16667], [4, 0.16667], [5, 0.16667], [6, 0.16667]]
 *     输出为二维数组。每一个值,第一个表示数字, 第二个表示概率。
 *
 * 示例1
 *
 * 输入
 *
 *     1
 *
 * 输出
 *
 *   [[1, 0.16667], [2, 0.16667], [3, 0.16667], [4, 0.16667], [5, 0.16667], [6, 0.16667]]
 */
public class Dice {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        while(scanner.hasNext()){
            int N=scanner.nextInt();
            int[][] dice=new int[N+1][6*N+1];
            for(int i=1;i<=6;i++)
                dice[1][i]=1;
            for(int i=2;i<=N;i++)
                for(int j=N;j<=6*N;j++)
                    for(int k=1;j-k>0 && k<=6;k++) {
                        dice[i][j] += dice[i][j - k];
                    }
            double total=Math.pow(6,N);

            ArrayList<ArrayList<String>> list=new ArrayList<>();
            for(int i=N;i<=6*N;i++){
                ArrayList<String> item=new ArrayList<>();
                item.add(Integer.toString(i));
                item.add(String.format("%.5f",dice[N][i]/total));
                list.add(item);
            }
            System.out.println(list.toString());
        }
        scanner.close();
    }
}
posted @ 2018-04-25 11:14  Neptune15  阅读(446)  评论(0编辑  收藏  举报