2017年网易校招笔试JAVA研发编程题

    尝试挑战了下网易2017校招的笔试编程题,共三题,AC第一题,第二题思考了很久勉强用一种low逼的方式完成,第三题没有完成,希望路过的ACM大神点醒。下面附上原题和我的解法,不喜勿喷。

    第一题:rev翻转

    实现一个rev操作,使得一个整数反转,如输入"123",输出"321",并去掉前导0,如输入“100”,输出"1"。然后输入两个数a,b,输出rev(rev(a)+rev(b))的结果。

    输入输出示例:

    输入:

    100 322

    输出:

    422

    解题思路:这题较为简单,只要能写出rev函数就可以解决问题。我采用的方法是从个位开始逐个提取数字拼接字符串的方式实现,设置首0标志,凡遇到0则剔除,当遇到非0数字时,取消首0检验。不多说,附上代码:

    

import java.util.Scanner;

public class Main {
	public static int rev(int a){
		StringBuffer string =new StringBuffer();
		int b = 0 ;
		boolean flag=true;
		while(a>0){
			b = a%10;
			a = (a-b)/10;
			if(flag){
				if(b!=0){
					flag = false;
					string.append(Integer.toString(b));
				}
			}else{
				string.append(Integer.toString(b));
			}
		}
		return Integer.parseInt(string.toString());
	}
	
	
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {//注意while处理多个case
            int a = in.nextInt();
            int b = in.nextInt();
            System.out.println(rev(rev(a)+rev(b)));
        }
	}

}

     第二题:暗黑的字符串

     使用“A”,“B”,“C” 三个字符构建字符串,对于一个构建好的字符串,如果存在连续三个字符,“A”,“B”,“C” 三个字符刚好各出现一次,如“ABCA”,那么称这样的字符串是“纯净”的。如果找不到这样的连续三个字符满足条件,那么称这样的字符串是“暗黑”的,如“ABAA”。

    现在给定一个整数n,试输出能构成的n位暗黑字符串的个数。

    输入输出示例:

    输入:

    3

    输出:

    21

    分析:这题笔一开始笔者采用的是暴力穷举的方法,就是列出所3^n种可能,然后逐一判断是否暗黑来进行统计。在构建出所有的字符串时采用了递归的方法,即通过一位一位地增加位数的方式得到,算法复杂度较高。代码如下:

    

import java.util.Scanner;

public class Main {
	
	public static boolean isWhite(String testString){
		boolean flag = false;
		String[] abc = new String[]{"ABC","ACB","BAC","BCA","CBA","CAB"};
		for (int i = 0; i < abc.length; i++) {
			if(testString.contains(abc[i])){
				flag = true;
				break;
			}
		}
		return flag;
		
	}
	public static String[] generateABC(int n){
		String[] init = new String[]{"A","B","C"};
		if(n==1){
			return init;
		}else{
			String[] abc = generateABC(n-1);
			String[] ABC = new String[abc.length*init.length];
			for (int i = 0; i < abc.length; i++) {
				for (int j = 0; j < init.length; j++) {
					ABC[j*abc.length+i] =abc[i]+init[j];
				}
			}
			return ABC;
		}
		
	}
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        StringBuffer testString = new StringBuffer();
        if(n<3){
        	System.out.println((int)(Math.pow(3,n)));
        }else{
        	int count = 0;
        	String[] result = generateABC(n);
        	for (int i = 0; i <result.length; i++) {
				if(isWhite(result[i])){
					count++;
				}
			}
    		
        	System.out.println(result.length-count);
        }
	}

}

   然后很快发现,这种写法在n=14时就坚持不住内存溢出了。

224757_pboG_2841107.png

于是请教了ACM高手,在高手的指点下,使用了数位DP算法,完成了此题的求解。代码如下:

import java.util.Scanner;

/**
 * 数位DP求解
 * @author shenwc
 *
 */
public class DpResovle {
	private static int[][] blacks ;
	private static boolean flag = true;//标记用以判断是否是首次调用
	public static  int[][] BlackCount (int length){
		if(flag){
			blacks = new int[length+1][4];
			flag =false;
		}
		if(length==3){
			//用二维数组blacks 存储暗黑字符串的个数
			//第一个维度代表字符串长度
			//  第二个维度的代表末尾状况
			// 0 代表末尾以AAA,BBB,或CCC结尾
			// 1  代表末尾以AAB,AAC,BBC,BBA,CCA,CCB结尾
			// 2 代表末尾以ABA,CBC,ACA,BCB,BAB,CAC结尾
			// 3 代表末尾以ABB,ACC,BCC,BAA,CAA,BAA结尾
			blacks[3][0] =3;
			blacks[3][1] =6;
			blacks[3][2] =6;
			blacks[3][3] =6;
		}else {
			BlackCount (length-1);
			blacks[length][0] = blacks[length-1][0]+blacks[length-1][3];
			blacks[length][1] = 2*(blacks[length-1][0]+blacks[length-1][3]);
			blacks[length][2] = blacks[length-1][1]+blacks[length-1][2];
			blacks[length][3] = blacks[length-1][1]+blacks[length-1][2];
		}
		return blacks;
	}
	
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        StringBuffer testString = new StringBuffer();
        if(n<3){
        	System.out.println((int)(Math.pow(3,n)));
        }else{
        	long time1 = System.currentTimeMillis();
        	int[][] result = BlackCount(n);
        	int count = 0;
        	for (int i = 0; i < 4; i++) {
				count+=result[n][i];
			}
        	System.out.println(count);
        	long time2 = System.currentTimeMillis();
        	System.out.println("用时:"+(time2-time1)+"ms");
        }
	}

}

 

 第三题:回文序列

    对于{1,2,1},{345},{2,3,3,2}这样对称的序列我们称之为回文序列。

    现在对于任意一个输入的序列,如{1,2,3,4},我们有一种操作,将相邻两个数相加并放回到这两个数原来的位置。对于{5,2,3,4},可以通过一次操作变为{7,3,4},两次操作变为{7,7}。

    现在试求出对于任意一个输入的序列,将其变为回文序列的最小步数。

    

    输入输出示例:

    输入:

    4(代表序列个数)

    5 2 3 4

    输出:

    2

    分析:本题笔者没有写出代码。不知道这题是否可以用动态规划的方法求解,如果可以,还请大神指教。

转载于:https://my.oschina.net/shenwc/blog/746262

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值