[算法]2018年阿里巴巴数据研发工程师编程题

题目:

思路:

这道题开始我完全没明白在讲啥,可能是我自己算法这块训练太少了吧,也是看了好久才明白。开始说“向三位同学提到。。。”,我以为除了两位同学之外还有别人,额,好吧,并没有。。。还有它的输入输出范例开始折叠着,完全没看到好吧。。。并且输入范例给的两个参数,给的代码模板的方法就传了一个参数,也是醉了。。。这种其他因素影响了我很多时间,好了,不吐槽了,言归正传!

最开始的思路是利用四叉树,如果0代表当天还清,1代表当天没有还清,还有欠款。那么第一天两个人(小波和小钱)有四种情况00,01,10,11。第二天以此类推,总共有4的3次方种情况,也就是说遍历四叉树即可。但是这种方法太麻烦。

魏印福给出的另一种思路简直太赞,一共需要做6种决策:1、第一天,给甲还不?2、第一天,给乙还不;3、第二天,给甲还不?4、第二天,给乙还不;。。。这样总共有2的6次方种情况。他想的是用二进制的方式表示:0到63,用二进制表示成000000到111111,这样一来我就可以第一位代表第一天是否还清小波,第二位代表第一天是否还清小钱,第三位代表第二天是否还清小波,第四位代表第二天是否还清小钱,第五位代表第三天是否还清小波,第六位代表第三天是否还清小钱。这样一来他根据二进制的移位操作便可以算出三种规则累计的失信分。部分代码如下:

package com.darrenchan;

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Main {

    static final int N = 1 << 6;

    /**
     * 某个人没有还款,扣一分
     */
    static int rule0(int x) {
        int ans = 0;
        for (int i = 0; i < 6; i++) {
            if ((x & (1 << i)) != 0) {
                ans++;
            }
        }
        return ans;
    }

    /**
     * 同一天内一点都没还款,扣一分
     */
    static int rule1(int x) {
        int ans = 0;
        for (int i = 0; i < 6; i += 2) {
            if ((x & (1 << i)) != 0 && ((x & (1 << (i + 1))) != 0))
                ans++;
        }
        return ans;
    }

    /**
     * 三天都存在逾期记录,扣一分
     */
    static int rule2(int x) {
        int ans = 0;
        for (int i = 0; i < 6; i += 2) {
            if ((x & (1 << i)) != 0 || (x & (1 << (i + 1))) != 0) {
                ans++;
            }
        }
        if (ans == 3)
            return 1;
        else
            return 0;
    }

    /**
     * 给决策x进行打分
     */
    static int parse(int x) {
        return rule0(x) + rule1(x) + rule2(x);
    }

    public static void main(String[] args) {
        int sum = 1 << 6;//一共有64种情况
        for (int i = 0; i < sum; i++) {
            System.out.println(Integer.toBinaryString(i) + ":" + parse(i));
        }
    }
}

根据其思路,我没有用二进制的移位操作,而是把二进制转成字符串,然后操作字符串,我想的代码如下:

package com.darrenchan;

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

public class Main2 {
    public static void main(String[] args) {
        int num = 1 << 6;// 一共情况
        List<String> list = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            String str = Integer.toBinaryString(i);
            // 如果不是6位,则进行补齐
            StringBuilder sb = new StringBuilder(str);
            if (str.length() < 6) {
                for (int j = 0; j < 6 - str.length(); j++) {
                    sb.insert(0, 0);
                }
            }
            list.add(sb.toString());
        }
        for (String item : list) {
            int score = getFinalScore(item);
            System.out.println(item + ":" + score);
        }

    }

    /**
     * 传入字符串,获取失信分数
     * @param list
     * @return
     */
    private static int getFinalScore(String item) {
        int score = 0;
        // 匹配rule1
        for (int i = 0; i < item.length(); i++) {
            if (‘1‘ == item.charAt(i)) {
                score++;
            }
        }
        // 匹配rule2
        if(item.substring(0, 2).equals("11")) score++;
        if(item.substring(2, 4).equals("11")) score++;
        if(item.substring(4).equals("11")) score++;
        // 匹配rule3
        int sum = 0;
        for (int i = 0; i < item.length(); i += 2) {
            sum += (item.charAt(i) == ‘1‘ || item.charAt(i + 1) == ‘1‘) ? 1 : 0;
        }
        if (sum == 3)
            score++;

        return score;
    }
}

结果展示为:

000000:0
000001:1
000010:1
000011:3
000100:1
000101:2
000110:2
000111:4
001000:1
001001:2
001010:2
001011:4
001100:3
001101:4
001110:4
001111:6
010000:1
010001:2
010010:2
010011:4
010100:2
010101:4
010110:4
010111:6
011000:2
011001:4
011010:4
011011:6
011100:4
011101:6
011110:6
011111:8
100000:1
100001:2
100010:2
100011:4
100100:2
100101:4
100110:4
100111:6
101000:2
101001:4
101010:4
101011:6
101100:4
101101:6
101110:6
101111:8
110000:3
110001:4
110010:4
110011:6
110100:4
110101:6
110110:6
110111:8
111000:4
111001:6
111010:6
111011:8
111100:6
111101:8
111110:8
111111:10

最后再根据题目要求转换成需要输出的字符串语句,并且写一个求指定日期的后一天的方法,这个就不赘述了。

原文地址:https://www.cnblogs.com/DarrenChan/p/8542792.html

时间: 2024-07-30 11:33:05

[算法]2018年阿里巴巴数据研发工程师编程题的相关文章

求职 | 华为研发工程师编程题个人题解【C++】【Python】

华为研发工程师编程题[C++][Python][数学][数组][字符串] 问题1 有这样一道智力题:"某商店规定:三个空汽水瓶可以换一瓶汽水.小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?"答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子.然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板.如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝? 输入描述: 输入文件最多包

搜狐2016研发工程师编程题

1.[编程题]马戏团 搜狐员工小王最近利用假期在外地旅游,在某个小镇碰到一个马戏团表演,精彩的表演结束后发现团长正和大伙在帐篷前激烈讨论,小王打听了下了解到, 马戏团正打算出一个新节目“最高罗汉塔”,即马戏团员叠罗汉表演.考虑到安全因素,要求叠罗汉过程中,站在某个人肩上的人应该既比自己矮又比自己瘦,或相等. 团长想要本次节目中的罗汉塔叠的最高,由于人数众多,正在头疼如何安排人员的问题.小王觉得这个问题很简单,于是统计了参与最高罗汉塔表演的所有团员的身高体重,并且很快找到叠最高罗汉塔的人员序列.

华为2016研发工程师编程题:字符集合

字符集合 输入一个字符串,求出该字符串包含的字符集合 输入描述: 每组数据输入一个字符串,字符串最大长度为100,且只包含字母,不可能为空串,区分大小写. 输出描述: 每组数据一行,按字符串原有的字符顺序,输出字符集合,即重复出现并靠后的字母不输出. 输入例子: abcqweracb 输出例子: abcqwer 解题 标记法时间复杂度太差了,可以用HashMap增加了空间复杂度 我的标记法 import java.util.Scanner; public class Main{ public s

网易2016研发工程师编程题:路灯

路灯 一条长l的笔直的街道上有n个路灯,若这条街的起点为0,终点为l,第i个路灯坐标为ai,每盏灯可以覆盖到的最远距离为d,为了照明需求,所有灯的灯光必须覆盖整条街,但是为了省电,要是这个d最小,请找到这个最小的d. 输入描述: 每组数据第一行两个整数n和l(n大于0小于等于1000,l小于等于1000000000大于0).第二行有n个整数(均大于等于0小于等于l),为每盏灯的坐标,多个路灯可以在同一点. 输出描述: 输出答案,保留两位小数. 输入例子: 7 1515 5 3 7 9 14 0

网易2016实习研发工程师编程题

牛客网上的题 1 比较重量 小明陪小红去看钻石,他们从一堆钻石中随机抽取两颗并比较她们的重量.这些钻石的重量各不相同.在他们们比较了一段时间后,它们看中了两颗钻石g1和g2.现在请你根据之前比较的信息判断这两颗钻石的哪颗更重. 给定两颗钻石的编号g1,g2,编号从1开始,同时给定关系数组vector,其中元素为一些二元组,第一个元素为一次比较中较重的钻石的编号,第二个元素为较轻的钻石的编号.最后给定之前的比较次数n.请返回这两颗钻石的关系,若g1更重返回1,g2更重返回-1,无法判断返回0.输入

网易2016 实习研发工程师 [编程题]二叉树

传送门 有一棵二叉树,树上每个点标有权值,权值各不相同,请设计一个算法算出权值最大的叶节点到权值最小的叶节点的距离.二叉树每条边的距离为1,一个节点经过多少条边到达另一个节点为这两个节点之间的距离. 给定二叉树的根节点root,请返回所求距离. 题解: 给每个节点编号(0 - total),用map记录每个节点的父节点 找出最大权值叶子节点 和 最小权值 叶子节点的编号 然后就是寻找最近公共祖先了 1 /* 2 struct TreeNode { 3 int val; 4 struct Tree

网易2016研发工程师编程题:扫描透镜

扫描透镜 在N*M的草地上,提莫种了K个蘑菇,蘑菇爆炸的威力极大,兰博不想贸然去闯,而且蘑菇是隐形的.只 有一种叫做扫描透镜的物品可以扫描出隐形的蘑菇,于是他回了一趟战争学院,买了2个扫描透镜,一个 扫描透镜可以扫描出(3*3)方格中所有的蘑菇,然后兰博就可以清理掉一些隐形的蘑菇. 问:兰博最多可以清理多少个蘑菇? 输入描述: 第一行三个整数:N,M,K,(1≤N,M≤20,K≤100),N,M代表了草地的大小; 接下来K行,每行两个整数x,y(1≤x≤N,1≤y≤M).代表(x,y)处提莫种了

比较重量 网易2016实习研发工程师编程题

题目: 小明陪小红去看钻石,他们从一堆钻石中随机抽取两颗并比较她们的重量.这些钻石的重量各不相同.在他们们比较了一段时间后,它们看中了两颗钻石g1和g2.现在请你根据之前比较的信息判断这两颗钻石的哪颗更重. 给定两颗钻石的编号g1,g2,编号从1开始,同时给定关系数组vector,其中元素为一些二元组,第一个元素为一次比较中较重的钻石的编号,第 二个元素为较轻的钻石的编号.最后给定之前的比较次数n.请返回这两颗钻石的关系,若g1更重返回1,g2更重返回-1,无法判断返回0.输入数据保证合 法,不

网易2016 实习研发工程师 [编程题]寻找第K大 and leetcode 215. Kth Largest Element in an Array

传送门 有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数. 给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在. 测试样例: [1,3,5,2,2],5,3 返回:2 note: 注意手写快排的时候: while(i < j) { while(j > i && a[j] > a[left]) j--; while(i < j && a[i] <= a[left]) i++; if(i