网易2018校园招聘编程题

版权声明:版权所有 https://blog.csdn.net/leechengqian/article/details/78379759

[编程题] 魔法币

时间限制:1秒

空间限制:32768K

小易准备去魔法王国采购魔法神器,购买魔法神器需要使用魔法币,但是小易现在一枚魔法币都没有,但是小易有两台魔法机器可以通过投入x(x可以为0)个魔法币产生更多的魔法币。

魔法机器1:如果投入x个魔法币,魔法机器会将其变为2x+1个魔法币

魔法机器2:如果投入x个魔法币,魔法机器会将其变为2x+2个魔法币

小易采购魔法神器总共需要n个魔法币,所以小易只能通过两台魔法机器产生恰好n个魔法币,小易需要你帮他设计一个投入方案使他最后恰好拥有n个魔法币。

输入描述:

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

输出描述:

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

输入例子1:

10

输出例子1:

122
package Netease2018Campus;

import java.util.Scanner;

import java.util.Stack;

public class MagicCoin {

        public static void main(String[] args){

            Scanner scan = new Scanner(System.in);

            /*

            因为选择一就得奇数,

            选择二就得偶数,

            那么对于n来说,

            最后一步只有一种可能,

            n为奇数则选择了一,

            n为偶数则选择了二。

             */

            while(scan.hasNext()){

                Stack<Integer> stack=new Stack<Integer>();

                int n=scan.nextInt();

                int count=0;

                while(n>0){

                    if(n%2==0)

                    {

                        n=(n-2)/2;

                        stack.push(2);

                    }else{

                        n=(n-1)/2;

                        stack.push(1);

                    }

                    count++;

                }

                while(!stack.isEmpty())

                    System.out.print(stack.pop());

                System.out.println();

            }

        }

}
 

[编程题] 相反数

时间限制:1秒

空间限制:32768K

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

输入描述:

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

输出描述:

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

输入例子1:

1325

输出例子1:

6556
package Netease2018Campus;

import java.util.Scanner;

public classReverseNum {

    public static void main(String[] args){

        Scanner scan = new Scanner(System.in);

        while(scan.hasNext()){

            int num=scan.nextInt();

            StringBuilder sb=new StringBuilder();

            sb.append(num);

            int reverse=Integer.parseInt(sb.reverse().toString());

            System.out.println(num+reverse);

        }

    }

}
 

[编程题] 字符串碎片

时间限制:1秒

空间限制:32768K

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

输入描述:

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

输出描述:

输出一个整数,表示所有碎片的平均长度,四舍五入保留两位小数。
如样例所示: s = "aaabbaaac"
所有碎片的平均长度 = (3 + 2 + 3 + 1) / 4 = 2.25

输入例子1:

aaabbaaac

输出例子1:

2.25
测试用例:
eeecabbccccbdbbaaabbbcaaaabbbdbccccddddabeeaaabbbe
对应输出应该为:
2.17
packageNetease2018Campus;

import java.util.Scanner;

public classStringFragmeng {

        public static void main(String[] args){

            Scanner scan = new Scanner(System.in);

            while(scan.hasNext()){

                String str=scan.nextLine();

               double len=str.length();

               double count=1;//片段数

               for(int i=1;i<len;i++)

                   if(str.charAt(i)!=str.charAt(i-1))

                       count++;

               double average=len/count;

               System.out.println(newjava.text.DecimalFormat("#.00").format(average));

            }

        }

    }
 

[编程题] 游历魔法王国

时间限制:1秒

空间限制:32768K

魔法王国一共有n个城市,编号为0~n-1号,n个城市之间的道路连接起来恰好构成一棵树。

小易现在在0号城市,每次行动小易会从当前所在的城市走到与其相邻的一个城市,小易最多能行动L次。

如果小易到达过某个城市就视为小易游历过这个城市了,小易现在要制定好的旅游计划使他能游历最多的城市,请你帮他计算一下他最多能游历过多少个城市(注意0号城市已经游历了,游历过的城市不重复计算)。

输入描述:

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

输出描述:

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

输入例子1:

5 2
0 1 2 3

输出例子1:

3
 
解析
能够访问最多城市必然是一定要确保访问最长树链。假设最长路径为d,如果l<d,那最多就访问最长数链上的l+1个城市,如果l>d,那么只要确保能够访问完最长路径上的所有城市,l步数走完最后停在最长路径的最后一个节点上,这样才能访问最多的城市。此时除了访问最长路径上的节点每个耗费了1个步数,其他每个节点则需要2个步数(一去一回)。
 
packageNetease2018Campus;

import java.util.Scanner;

/*

访问最长路径上的节点每个耗费1个步数

其他每个节点2个步数,一去一回

 */

public class TravelKindom {

    static intn;//城市个数

    static int[]parent;

    static int l;//小易能行动的步数

    public static void main(String[] args){

        Scanner scan = new Scanner(System.in);

        while(scan.hasNext()){

            n=scan.nextInt();

            l=scan.nextInt();

            parent=new int[n];

            for(int i=0;i<n-1;i++)

               parent[i]=scan.nextInt();

            System.out.println(work());

        }

    }

    public static intwork(){

        int[] dp=new int[n];

        int height=0;//heigth为树高度

        for(int i=0;i<n-1;i++){

            /*

           编号i+1的城市与parent[i]相同,则到达i+1的路径为parent[i]城市路径+1

            */

           dp[i+1]=dp[parent[i]]+1;

            height=Math.max(height,dp[i+1]);

        }

        /*

        访问城市数比移动次数多1

        若行动步数小于树高度,最多访问次数l+1

        若行动次数大于树高度,最多访问节点数height+(leight-height)/2+1

         */

        if(l<height)

            return l+1;

        else

           return Math.min(n,height+(l-height)/2+1);//访问城市数一定小于n

    }

}

[编程题] 重排数列

时间限制:1秒

空间限制:100768K

小易有一个长度为N的正整数数列A = {A[1], A[2], A[3]..., A[N]}。

牛博士给小易出了一个难题:

对数列A进行重新排列,使数列A满足所有的A[i] * A[i + 1](1 ≤ i ≤ N - 1)都是4的倍数。

小易现在需要判断一个数列是否可以重排之后满足牛博士的要求。

输入描述:

输入的第一行为数列的个数t(1 ≤ t ≤ 10),
接下来每两行描述一个数列A,第一行为数列长度n(1 ≤ n ≤ 10^5)
第二行为n个正整数A[i](1 ≤ A[i] ≤ 10^9)

输出描述:

对于每个数列输出一行表示是否可以满足牛博士要求,如果可以输出Yes,否则输出No。

输入例子1:

2
3
1 10 100 
4
1 2 3 4

输出例子1:

Yes
No
测试用例:
10 50 948 633 70 638 306 326 158 63 555 426 689 653 863 422 958 594 130 946 839 450 667 957 16 378 768 791 382 678 668 884 353 24 84 574 301 330 617 881 951 424 721 690 674 127 219 356 962 377 780 822 94 460 666 134 892 90 396 866 982 26 98 718 610 512 840 223 320 690 418 534 476 588 81 453 435 917 246 509 9 647 68 464 157 961 441 676 332 640 231 558 402 435 274 277 7 680 358 174 779 357 505 550 590 513 65 359 179 93 60 840 28 703 590 234 888 362 753 684 125 592 467 854 159 781 711 7 42 668 723 569 5 925 427 662 319 267 100 933 230 646 189 427 862 895 934 83 490 782 448 64 230 858 242 998 608 646 908 916 410 864 282 35 688 959 95 450 222 671 741 796 635 589 945 356 233 268 526 775 99 375 473 625 425 418 519 833 414 79 744 148 67 793 924 125 51 576 268 559 109 867 329 438 79 105 972 715 763 221 50 230 92 206 152 286 295 537 705 305 924 368 243 194 123 617 915 225 871 182 701 62 917 801 467 769 252 220 468 935 613 853 94 796 293 591 169 306 805 40 31 746 686 455 190 717 5 869 181 4 291 155 545 814 695 668 570 481 502 257 720 953 518 313 82 302 572 8 748 706 641 409 459 537 404 960 600 242 687 496 828 834 443 53 64 148 924 40 720 756 454 590 130 392 264 544 624 206 879 443 612 655 305 65 365 477 561 414 544 625 875 713 678 298 914 293 170 321 267 641 827 660 387 114 373 132 556 691 490 712 22 897 64 605 857 826 732 685 385 436 29 12 577 105 729 634 777 274 614 20 674 588 472 314 270 916 574 116 936 584 179 572 528 791 318 360 912 790 474 982 34 414 574 100 684 296 666 384 772 246 946 608 786 660 862 228 500 660 304 284 578 890 234 72 261 769 864 770 750 553 7 875 367 183 57 27 260 8 749 469 693 25 225 782 582 528 642 35 572 45 936 622 285 97 539 425 192 261 220 122 227 771 658 79 130 712 612 542 450 323 781 625 932 18 180 504 704 363 550 263 566 24 54 4 514 829 375 251 971 438 655 671 761 401 256 451 789 921 287 199 842 448 307 313 785 556 678 105 201 335 212 608 804 296 742 985 891 638 191 996 485 615 414 327 610 992 406 919 640 593 924 15 674 343 561 248 760 413 908 640 481 187 131 33 202 452 74 802 788 372 436 68 150 556 538 878 356 658 978 838 418 447 776 159 224 112 674 964 223 872 813 341 60 838 255 949 267
对应输出应该为:
No No No No No Yes Yes No No Yes
packageNetease2018Campus;

import java.util.Scanner;

public class RearrangeArray {

    public static void main(String[] args){

        Scanner scan = new Scanner(System.in);

        while(scan.hasNext()){

            int n=scan.nextInt();//第一行,数列的个数

           for(int i=0;i<n;i++){

               int count=scan.nextInt();//两行中的第一行,数列长度

               int count1=0,count2=0,count4=0;

               int[]nums=new int[count];

               for(int j=0;j<count;j++) {

                   nums[j] = scan.nextInt();//两行中的第二行,数列内容

               }

               for(int j=0;j<count;j++){//统计能被2整除的数的个数

                   if(nums[j]%4==0)//统计能被4整除的数的个数

                       count4++;

                   else if(nums[j]%2==0)//统计能被2整除但不能被4整除的数的个数

                       count2++;

                   else

                       count1++;//奇数个数

               }

               if(count2%2==0)//偶数个2的倍数

               {

                   if (count4>= count1 -1)//可排成一行,从奇数开始,奇数与4的倍数交替出现

                       System.out.println("Yes");

                   else

                       System.out.println("No");

               }

               else{

                   if(count4 >=count1)//2的倍数部分需要一个4

                       System.out.println("Yes");

                   else

                       System.out.println("No");

               }

            }

        }

    }

}

 

[编程题] 最长公共子括号序列

时间限制:1秒

空间限制:100768K

一个合法的括号匹配序列被定义为:

1. 空串""是合法的括号序列

2. 如果"X"和"Y"是合法的序列,那么"XY"也是一个合法的括号序列

3. 如果"X"是一个合法的序列,那么"(X)"也是一个合法的括号序列

4. 每个合法的括号序列都可以由上面的规则生成

例如"", "()", "()()()","(()())", "(((()))"都是合法的。

从一个字符串S中移除零个或者多个字符得到的序列称为S的子序列。

例如"abcde"的子序列有"abe","","abcde"等。

定义LCS(S,T)为字符串S和字符串T最长公共子序列的长度,即一个最长的序列W既是S的子序列也是T的子序列的长度。

小易给出一个合法的括号匹配序列s,小易希望你能找出具有以下特征的括号序列t:

1、t跟s不同,但是长度相同

2、t也是一个合法的括号匹配序列

3、LCS(s, t)是满足上述两个条件的t中最大的

因为这样的t可能存在多个,小易需要你计算出满足条件的t有多少个。

如样例所示: s = "(())()",跟字符串s长度相同的合法括号匹配序列有:

"()(())", "((()))","()()()", "(()())",其中LCS("(())()", "()(())" )为4,其他三个都为5,所以输出3.

输入描述:

输入包括字符串s(4 ≤ |s| ≤ 50,|s|表示字符串长度),保证s是一个合法的括号匹配序列。

输出描述:

输出一个正整数,满足条件的t的个数。

输入例子1:

(())()

输出例子1:

3

解析:

根据题意,要想使得 LCS 最大,删去任意一个字符即可获得 LCS = |s| - 1 ,再把该字符插到与原来不同的任意位置可以维持原长度,而不影响 LCS 的计算。

因此最暴力的做法是枚举每个字符,把它插入到任意位置,判合法,去重,累计。

优化 1 :插入是插到指定位置的字符之前,如果插入的字符和该位置的字符相同,则插入后还是原字符串,可以跳过这种情况。否则最后的结果要 - 1 。

优化 2 :左右两边一定是左右括号,不用移动它们。但字符却可以插到它们的后面。

判合法:实际上就是括号匹配的平衡性。在这里,如果我们从前到后遍历,左括号可以暂时多于右括号,但不可以少于,因为能够闭合右括号的左括号都在左边了。每次成功闭合一对括号把数量 - 1 ,得到负数说明不平衡。

package Netease2018Campus;
 

//StringBuilder对于经常改变字符串来说效率最高

//两次循环,第一次遍历选择不同位置的,第二次将其插入到剩余字符串任意位置

//最后添加到set中去重,最后将原来的一次减去

import java.util.HashSet;

import java.util.Scanner;

import java.util.Set;

public classLongestSubstring1 {

    public static booleanisok(String str) {

       int left=0,right=0;

        for(int i=0;i<str.length();i++) {

            if(str.charAt(i)=='(')

               left++;

            else

               right++;

            if(right>left)//右括号多于左括号,不合法

               break;

        }

        if(right==left)

            return true;

        return false;

    }

    public static voidmain(String[] args) {

        Scanner in=new Scanner(System.in);

        while(in.hasNext()){

            String str=in.nextLine();

            Set<String> set=new HashSet<>();//使用set去除重复序列

           StringBuilder temp;

            StringBuilder temp1;

            for(int i=0;i<str.length();i++) {

               temp=new StringBuilder();

               /*

               * substring(int beginIndex,intendIndex)

                * 从beginIndex开始取

               * 到endIndex结束

               * 不包括endIndex的字符

               * */

               temp.append(str.substring(0,i)+str.substring(i+1));//temp不包含序号为i(第i+1个)的括号

               for(int j=0;j<=temp.length();j++) {//序号为i的括号找位置插入

                   temp1=newStringBuilder();

                   temp1.append(temp.substring(0, j)+String.valueOf(str.charAt(i))+temp.substring(j));

                   if(isok(temp1.toString()))

                       set.add(temp1.toString());

               }

            }

            System.out.println(set.size()-1);//-1除去s序列

        }

    }

} 

 

[编程题] 合唱

时间限制:2秒

空间限制:131072K

小Q和牛博士合唱一首歌曲,这首歌曲由n个音调组成,每个音调由一个正整数表示。

对于每个音调要么由小Q演唱要么由牛博士演唱,对于一系列音调演唱的难度等于所有相邻音调变化幅度之和, 例如一个音调序列是8, 8, 13, 12, 那么它的难度等于|8 - 8| + |13 - 8| + |12 - 13| = 6(其中||表示绝对值)。

现在要对把这n个音调分配给小Q或牛博士,让他们演唱的难度之和最小,请你算算最小的难度和是多少。

如样例所示: 小Q选择演唱{5, 6}难度为1, 牛博士选择演唱{1, 2, 1}难度为2,难度之和为3,这一个是最小难度和的方案了。

输入描述:

输入包括两行,第一行一个正整数n(1 ≤ n ≤ 2000) 第二行n个整数v[i](1 ≤ v[i] ≤ 10^6), 表示每个音调。

输出描述:

输出一个整数,表示小Q和牛博士演唱最小的难度和是多少。

输入例子1:

5
1 5 6 2 1

输出例子1:

3
packageNetease2018Campus; 

import java.util.*; 

public classChorus {//合唱

    public static void main(String[] args){

        Scanner scan=new Scanner(System.in);

        while(scan.hasNext()){

            int n = scan.nextInt();

            int[] a =new int[n];

            for(inti=0; i<n; i++)a[i]=scan.nextInt();

            int[][]dp =new int[n+1][n+1];

            dp[n][n]=Integer.MAX_VALUE;

            for(int i=n-1; i>=0; i--){

               for(int j=n-1; j>=0; j--){

                   int next =Math.max(i, j) +1;//下一个要演唱的位置

                   //Math.abs(a[next-1]-a[i-1])表示下一个音调i唱时的音调变化绝对值

                   dp[i][j] = Math.min(dp[next][j]+(i==0?0:Math.abs(a[next-1]-a[i-1])),dp[i][next]+(j==0?0:Math.abs(a[next-1]-a[j-1])));

               }

            }

            System.out.println(dp[0][0]);

        }

    }

}

[编程题] 射击游戏

时间限制:1秒

空间限制:32768K

小易正在玩一款新出的射击游戏,这个射击游戏在一个二维平面进行,小易在坐标原点(0,0),平面上有n只怪物,每个怪物有所在的坐标(x[i], y[i])。小易进行一次射击会把x轴和y轴上(包含坐标原点)的怪物一次性消灭。

小易是这个游戏的VIP玩家,他拥有两项特权操作:

1、让平面内的所有怪物同时向任意同一方向移动任意同一距离

2、让平面内的所有怪物同时对于小易(0,0)旋转任意同一角度

小易要进行一次射击。小易在进行射击前,可以使用这两项特权操作任意次。

小易想知道在他射击的时候最多可以同时消灭多少只怪物,请你帮帮小易。

如样例所示:

所有点对于坐标原点(0,0)顺时针或者逆时针旋转45°,可以让所有点都在坐标轴上,所以5个怪物都可以消灭。

输入描述:

输入包括三行。
第一行中有一个正整数n(1 ≤ n ≤ 50),表示平面内的怪物数量。
第二行包括n个整数x[i](-1,000,000 ≤ x[i] ≤ 1,000,000),表示每只怪物所在坐标的横坐标,以空格分割。
第二行包括n个整数y[i](-1,000,000 ≤ y[i] ≤ 1,000,000),表示每只怪物所在坐标的纵坐标,以空格分割。

输出描述:

输出一个整数表示小易最多能消灭多少只怪物。

输入例子1:

5
0 -1 1 1 -1
0 -1 -1 1 1

输出例子1:

5

测试用例:

9

0 -3 3 3 -3 0 0 3 -3

0 -3 -3 3 3 3 -3 0 0

对应输出应该为:

5

测试用例:

50

9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 99 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1718 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 4344 45 46 47 48 49

对应输出应该为:

50

测试用例:

50

-301563 714382 940434 768504 195 959350 13212532 31412 -893508 -546715 134712 68 5 -517857 374406 560379 150226 39 176202 -856465 17 483518 4 26 160 181 570660 794784 225 185272 46572 192 -38038034 25 48 174094 -901951 7 198 564061 -559737 -971731 -465785 67 188 -738639144167

-416652 972572 -451947 354396 45 -365014137 291391 -265483 -923344 -719789 125652 82 145 -610115 507468 343284 -374914111 26 52 376367 133 -551928 146 124 10 31 -574912 264828 75 797089 958910 42-483260 116 125 102 988193 -994605 143 48 208105 -690643 -58337 96189 83 38884870 -403893

对应输出应该为:

21

packageNetease2018Campus;

import java.util.HashSet;

import java.util.Scanner;

import java.util.Set;

 

public classShootingGame1 {

    public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);

        while (scan.hasNext()){

            int n =scan.nextInt();

            int[] x =new int[n];//横坐标

           int[] y =new int[n];//纵坐标

           for (int i = 0; i < n; i++)

               x[i] = scan.nextInt();

            for (inti = 0; i < n; i++)

               y[i] = scan.nextInt();

            if(n< 4)

               System.out.println(n);//零个点、一个点或两个点,一定可以消除

           else {

               int max =3;

               for (int i = 0; i < n; i++) {

                   for (int j = i + 1; j < n; j++) {

                       int xcount =2, ycount = 0, ymax= 0;

                       Set<Integer> set= new HashSet<Integer>();//记录与确定x轴的两个点在同一直线上的点,避免在y轴上重复计数

                       set.add(i);

                       set.add(j);

                       for (int k = 0; k < n; k++) {

                           if (k == i || k == j)

                               continue;

                           if (((y[k] - y[i])*(x[i]-x[j])) == ((y[i]-y[j])* (x[k] -x[i])) ){

                               set.add(k);

                               xcount++;

                           }

                       }

                       for (int k = 0; k < n; k++) {//另一条直线的点从0开始,只要不在x轴上就行

                           if (set.contains(k))

                               continue;

                            else

                               ycount=1;//y轴上的一个点

                           for (int l = k + 1; l< n; l++) {

                               if (set.contains(l))

                                   continue;

                               else if (((y[l]- y[k])*(y[i]-y[j])) == ((x[j]-x[i]) * (x[l] - x[k])))//y轴上的其他点

                                   ycount++;

                           }

                           if (ycount > ymax)

                               ymax = ycount;

                       }

                       if (xcount + ymax > max){

                           max = xcount +ymax;

                       }

                   }

               }

               System.out.println(max);

            }

        }

    }

}

猜你喜欢

转载自blog.csdn.net/leechengqian/article/details/78379759