今日头条2017后端工程师实习生笔试题 - 题解

今日头条2017后端工程师实习生笔试题

最大映射

题意
给n(不超过50)个字符串,每个字符串(长度不超过12)由A-J的大写字符组成。要求将每个字符映射为0-9,使得每个字符串可以看作一个整数(不能有前导零),求这些字符串映射后得到数字的最大和值。(数据保证至少有一个字符不是任何字符串的首字母)

思路
根据字符所在的位置,累积统计每个字符的权值,从右到左权值分别为1, 10, 100, 1000.....
然后排序,从权值最小的到权值最大的依次映射为0-9,求和即为答案。

注意
由于每个字符串映射后得到的数字不能有前导零,因此需要记录哪些字符成为过首字母,成为过首字母的字符最终不能映射为0。所以排序后需要判断权值最小的字符是否成为过首字母,若是则需要从权值小到权值大找到第一个不为首字母的字符X,将它映射为0。在权值比X小的则依次晋级。

举例

A B C D E F G H I J
首字母 F F T F T T F T T T
权值 100 90 80 70 60 50 40 30 20 10
映射 9 8 7 6 5 4 3 2 1 0

由于 J 成为过首字母,因此不能映射为 0

所以最终结果应为

A B C D E F H I J G
首字母 F F T F T T T T T F
权值 100 90 80 70 60 50 30 20 10 40
映射 9 8 7 6 5 4 3 2 1 0

木棒拼图

题意
一个木棒集合,每根木棒知道长度,问能否用这些木棒构成一个面积大于0的简单多边形(不能自交)。数据有n次操作,每次操作要么增加一根长度为x的木棒,要么去掉一根长度为x的木棒,每次操作完后问剩下的木棒能否满足上述条件。

思路
要使这些木棒能构成一个面积大于0的简单多边形,只需满足最长的木棒短于剩下的所有木棒的总长。即多边形近乎为一条直线。
因此只需构造一个集合,从小到大存放木棒,每次操作更新总长度,判断 maxLen < sum - maxLen 即可。

魔法权值

题意
给n(不超过8)个字符串,每个字符串长度不超过20。把这些字符串全排列得到n!个字符串。一个字符串的权值等于把这个字符串循环左移 i 次后得到的字符串仍和原字符串全等的数量,i 的取值为 [1 , 字符串长度]。求这n!个字符串中有多少个权值为k。

思路
暴力解决。递归全排列得到所有字符串,每个字符串跑一遍求出k
import java.util.Scanner;

public class Main {

    private static String[] input = new String[8];
    private static String[] strs = new String[40320];
    private static int n, k;
    private static int cnt = 0;

    private static void createString() {
        class Iter {
            boolean[] mark = new boolean[n];
            void work(String prefix) {
                boolean tag = false;
                for (int i=0; i<n; ++i) {
                    if (mark[i] == false) {
                        tag = true;
                        mark[i] = true;
                        work(prefix + input[i]);
                        mark[i] = false;
                    }
                }
                if (tag == false) {
                    strs[cnt] = prefix;
                    ++cnt;
                }
            }
        }
        new Iter().work("");
    }

    private static int workWeight(String str) {
        char[] chars = str.toCharArray();
        int ans = 1;
        int len = chars.length;
        for (int i=1; i<len; ++i) {
            if (chars[i] == chars[0]) {
                int j = 1;
                for (; j<len; ++j) {
                    if (chars[(i+j)%len] != chars[j]) {
                        break;
                    }
                }
                ans += j == len ? 1 : 0;
            }
        }
        return ans;
    }

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        n = scan.nextInt();
        k = scan.nextInt();
        for (int i=0; i<n; ++i) {
            input[i] = scan.next();
        }
        createString();
        int ans = 0;
        for (int i=0; i<cnt; ++i) {
            if (workWeight(strs[i]) == k) {
                ++ans;
            }
        }
        System.out.println(ans);
    }
}

或与加

题意
给定两个正整数 x, k (0 < x, k < 2 0000 0000),求第k个满足 x + y = x | y 的 y (正整数)

思路
要使 x + y = x | y 则 x 和 y 的二进制表示1和1之间的位置应该是不重合的,即 x & y = 0
则把k的二进制表示依次对应到x的二进制表示上为0的位置,其余空位添上0则为答案

举例 n = 5, k = 3
5 -> 0b 0101
3 -> 0b 0011
ans  0b 1010
(将k的1依次放到n上0的位置,其余空位添上0)

注意
由于x,k最大范围为2亿,因此极限情况为 x = k = 2 ^ 30 - 1 = 0b111...1111(连续30个1),则最终答案为0b111...11100000...0000(30个1接30个0),60位,因此最终结果需要用long表示。
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int x = input.nextInt();
        int k = input.nextInt();
        StringBuilder sb = new StringBuilder();
        while (k > 0) {
            if ((x & 1) == 1) {
                sb.append(0);
            } else {
                sb.append(k & 1);
                k >>= 1;
            }
            x >>= 1;
        }
        long ans = Long.parseLong(sb.reverse().toString(), 2);
        System.out.println(ans);
    }
}

原文地址:https://www.cnblogs.com/corvey/p/8638435.html

时间: 2024-10-06 00:31:03

今日头条2017后端工程师实习生笔试题 - 题解的相关文章

今日头条2017后端工程师实习生笔试题

第二题: [编程题] 木棒拼图 有一个由很多木棒构成的集合,每个木棒有对应的长度,请问能否用集合中的这些木棒以某个顺序首尾相连构成一个面积大于 0 的简单多边形且所有木棒都要用上,简单多边形即不会自交的多边形. 初始集合是空的,有两种操作,要么给集合添加一个长度为 L 的木棒,要么删去集合中已经有的某个木棒.每次操作结束后你都需要告知是否能用集合中的这些木棒构成一个简单多边形. 输入描述: 每组测试用例仅包含一组数据,每组数据第一行为一个正整数 n 表示操作的数量(1 ≤ n ≤ 50000)

算法面试题-今日头条2017客户端工程师实习生笔试题4:或与加

今日头条2017客户端工程师实习生笔试题 题目: 这个题做到最后,时间不是很够,题目内容比较简单,求出第k个正整数符合x+y=x|y,然而这个k的取值范围非常大(k<=2000000000),所以可以不用考虑穷举法,当然,时间不够的话写个穷举试试运气也可以. 穷举法: 1 import java.util.Scanner; 2 3 /** 4 * Created by Administrator on 2016/9/6. 5 */ 6 7 public class Main { 8 public

今日头条2017后端工程师笔试题

1.最大映射 有 n 个字符串,每个字符串都是由 A-J 的大写字符构成.现在你将每个字符映射为一个 0-9 的数字,不同字符映射为不同的数字.这样每个字符串就可以看做一个整数,唯一的要求是这些整数必须是正整数且它们的字符串不能有前导零.现在问你怎样映射字符才能使得这些字符串表示的整数之和最大? 输入描述: 每组测试用例仅包含一组数据,每组数据第一行为一个正整数 n , 接下来有 n 行,每行一个长度不超过 12 且仅包含大写字母 A-J 的字符串. n 不大于 50,且至少存在一个字符不是任何

2018今日头条春招的一道笔试题 —— 通过改变枚举的变量进行枚举优化

题目如下: 这道题我们最先想到的做法,应该就是2重循环枚举数对,然后把数对放在set里去重,最后输出set的大小,即输出set.size( ).代码如下: 1 #include<iostream> 2 #include<set> 3 using namespace std; 4 5 int n, k, a[100000]; 6 set<pair<int, int>> mypairs; 7 8 int main() 9 { 10 cin >> n

【转】嵌入式软件工程师经典笔试题

嵌入式软件工程师经典笔试题 > 预处理器(Preprocessor) 1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在这想看到几件事情: 1). #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等) 2). 懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中 有多少秒而不是计算出实际的值,是更清晰而没有代价的. 3).

Java开发工程师上机笔试题

网上看到3道比较好的Java开发工程师上机笔试题,没有答案这里把答案写出来,给大家参考. 1.编一个程序,输入10个整数,并放在数组中,先降序输出所有的数,再统计并输出其中正数.负数和零的个数 package cn.Pigzhu.test; import java.util.Scanner; /**  * 控制台输入10个数字,并输入正负和零的个数  * @author xiaoyezhu  *  */ public class test { public static void main(St

诺基亚(Microsoft Devices Group)2014暑期实习生笔试题知识点

总结一下Microsoft Devices Group的软件类笔试题,所有笔试题分两份试卷,逻辑题一份和软件测试题一份,只总结技术题喽~题目全英文,只包含选择题和填空题,选择题居多,分单选和多选,多选题题目会标注出来.总体来说考察的很基础也很细节,难度适中.下面把记得的一些知识点总结一下下: *命名管道的定义. *主机A发送IP数据报给主机B,途中经过了5个路由器.试问在IP数据报的发送过程总共使用几次ARP(6次) *Linux系统下,给一个文件重命名(mv A,B) *考察无符号整型数和有符

转:嵌入式软件工程师经典笔试题

> 预处理器(Preprocessor) 1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)  #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在这想看到几件事情: 1). #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等) 2). 懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的. 3). 意识到这个表达式将使一个1

趋势科技2014年暑期实习生笔试题

题目: 有81匹赛马,9个赛道可以利用,每匹赛马的速度是恒定的,不计时但记录每场的名次,请问,赛几次可以得到前5名? 解答: 首先把81匹马分为9组,赛九场,然后把每场的第一名拿出来(刚好9匹),赛一场,得到前五名所在的组(后四名的组果断排除).此时可以确定第一名.然后在第一名的组中抽取2-5名(共四匹马),在第二名的组中抽取2-4名(共三匹马),在第三名的组中抽取2-3(共两匹马),在第四名的组中抽取第2名(共一匹马),此时剩下的马匹有(4+3+2+1+4=14匹),取14中的9匹赛一场,得到