网易2017秋招编程题集合-解题报告
2016-11-29 01:21
507 查看
1. 如果一个数字序列逆置之后跟原序列是一样的就称这样的数字序列为回文序列。例如:
{1, 2, 1}, {15, 78, 78, 15} , {112} 是回文序列,
{1, 2, 2}, {15, 78, 87, 51} ,{112, 2, 11} 不是回文序列。
现在给出一个数字序列,允许使用一种转换操作:
选择任意两个相邻的数,然后从序列移除这两个数,并用这两个数字的和插入到这两个数之前的位置(只插入一个和)。
现在对于所给序列要求出最少需要多少次操作可以将其变成回文序列。
解法: 从两边往中间靠,不等的取较小数合并它的相邻数
public class Main{
static int n,ans;
static int a[] = new int[55];
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
n = cin.nextInt();
for(int i=0;i<n;i++)
if(cin.hasNextInt())
a[i] = cin.nextInt();
cin.close();
dfs(0,n-1);
System.out.println(ans);
}
public static void dfs(int i,int j){
while(a[i]==a[j]){
++i;
--j;
if(j<=i)return ;
}
if(a[i]<a[j]){
a[i+1]+=a[i];
++i;
}else {
a[j-1]+=a[j];
--j;
}
ans++;
dfs(i,j);
}
}
2. 小易有一个圆心在坐标原点的圆,小易知道圆的半径的平方。小易认为在圆上的点而且横纵坐标都是整数的点是优雅的,小易现在想寻找一个算法计算出优雅的点的个数,请你来帮帮他。
例如:半径的平方如果为25
优雅的点就有:(+/-3, +/-4), (+/-4, +/-3), (0, +/-5) (+/-5, 0),一共12个点。
解法: 枚举四分之一个圆,勾股定理判断整数,最后考虑4个和坐标轴交点是否满足
import java.util.Scanner;
public class Main{
static int R,r,e,max;
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
R = cin.nextInt();
r = (int)(Math.sqrt(R));
if(r*r==R){e=4;max=r-1;}
else max = r;
int T,t;
int ans=0;
for(int i=1;i<=max;i++){
T = R-i*i;
t = (int)Math.sqrt(T);
if(t*t==T){
++ans;
}
}
System.out.println(ans*4+e);
cin.close();
}
}
3. 小易来到了一条石板路前,每块石板上从1挨着编号为:1、2、3.......
这条石板路要根据特殊的规则才能前进:对于小易当前所在的编号为K的 石板,小易单次只能往前跳K的一个约数(不含1和K)步,即跳到K+X(X为K的一个非1和本身的约数)的位置。 小易当前处在编号为N的石板,他想跳到编号恰好为M的石板去,小易想知道最少需要跳跃几次可以到达。
例如:
N = 4,M = 24:
4->6->8->12->18->24
于是小易最少需要跳跃5次,就可以从4号石板跳到24号石板
解法: 广度搜索,这题卡了一下,记忆搜索没达到优化效果,直接取出所有素数就能达到优化效果
import java.util.LinkedList;
import java.util.Scanner;
class Step{
int val;
int step;
public Step(int v,int s){
val = v;
step = s;
}
}
public class Main{
static int m,n;
static int r[]=new int[100005];
static int prime[] = new int[100005];
static LinkedList<Step> list = new LinkedList<Step>();
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
m = cin.nextInt();
n = cin.nextInt();
cin.close();
list.add(new Step(m,0));
Step t;
init();
while(!list.isEmpty()){
t = list.poll();
if(t.val==n){
System.out.println(t.step);
return ;
}
if(prime[t.val]==1)
for(int j=2;j<=(int)Math.sqrt(t.val);j++)
if(t.val%j==0){
if(t.val+j<=n&&(0==r[t.val+j]||r[t.val+j]>t.step+1)){
list.add(new Step(t.val+j,t.step+1));
r[t.val+j]=t.step+1;
}
if(t.val+t.val/j<=n&&(0==r[t.val+t.val/j]||r[t.val+t.val/j]>t.step+1)){
list.add(new Step(t.val+t.val/j,t.step+1));
r[t.val+t.val/j]=t.step+1;
}
}
}
System.out.println(-1);
}
static void init(){
prime[2]=0;
for(int i=2;i<=100000;i++)
if(prime[i]==0){
for(int j=2;i*j<=100000;j++)
prime[i*j]=1;
}
}
}
4.一个只包含'A'、'B'和'C'的字符串,如果存在某一段长度为3的连续子串中恰好'A'、'B'和'C'各有一个,那么这个字符串就是纯净的,否则这个字符串就是暗黑的。例如:
BAACAACCBAAA 连续子串"CBA"中包含了'A','B','C'各一个,所以是纯净的字符串
AABBCCAABB 不存在一个长度为3的连续子串包含'A','B','C',所以是暗黑的字符串
你的任务就是计算出长度为n的字符串(只包含'A'、'B'和'C'),有多少个是暗黑的字符串。
解法: 简单递推, 方案数 = 当前添加字符位置的前两位相同方案数 + 前两位不同方案数
dp[i] = dp[i-2]* 3 + (dp[i-1]-dp[i-2])*2
dp[i-2]表示前两位相同 , *3表示可去任意字符
dp[i-1]-dp[i-2] 表示在i-1位置,总方案数-和前位相同方案数,结果为两位不同的方案数,*2表示可取2种字符
import java.util.Scanner;
class Step{
int val;
int step;
public Step(int v,int s){
val = v;
step = s;
}
}
public class Main{
static int n;
static long dp[] = new long [33];
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
n = cin.nextInt();
cin.close();
dp[0]=0;dp[1]=3;dp[2]=9;
for(int i=3;i<=n;i++)
dp[i]=(dp[i-1]-dp[i-2])*2+dp[i-2]*3;
System.out.println(dp
);
}
}5. 对于一个整数X,定义操作rev(X)为将X按数位翻转过来,并且去除掉前导0。例如:
如果 X = 123,则rev(X) = 321;
如果 X = 100,则rev(X) = 1.
现在给出整数x和y,要求rev(rev(x) + rev(y))为多少?
解法:送分题
import java.util.Scanner;
public class Main{
static int n;
static long dp[] = new long [33];
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
n = cin.nextInt();
cin.close();
dp[0]=0;dp[1]=3;dp[2]=9;
for(int i=3;i<=n;i++)
dp[i]=(dp[i-1]-dp[i-2])*2+dp[i-2]*3;
System.out.println(dp
);
}
}
6.小易是一个数论爱好者,并且对于一个数的奇数约数十分感兴趣。一天小易遇到这样一个问题: 定义函数f(x)为x最大的奇数约数,x为正整数。 例如:f(44) = 11.
现在给出一个N,需要求出 f(1) + f(2) + f(3).......f(N)
例如: N = 7
f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) = 1 + 1 + 3 + 1 + 5 + 3 + 7 = 21
小易计算这个问题遇到了困难,需要你来设计一个算法帮助他。
解法: 卡了很久, N/2^x 表示1-N中2^x的倍数的数的个数, 其实就是等差数列规模不断缩小
如 8:
8/2^0 : 1 3 5 7 9
8/2^1: 1 3
8/2^2: 1
8/2^3: 1
ans = 1+3+5+7+9 + 1+3 +1 +1
import java.util.Scanner;
public class Main{
static int n;
static long ans;
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
n = cin.nextInt();
cin.close();
ans+= add(n);
for(int i=1;(1<<i)<=n;i++){
ans+= add(n/(1<<i));
}
System.out.println(ans);
}
static long add(int n){
long x = n/2+((n%2==0)?0:1);
return x*x;
}
}
7. 小易去附近的商店买苹果,奸诈的商贩使用了捆绑交易,只提供6个每袋和8个每袋的包装(包装不可拆分)。 可是小易现在只想购买恰好n个苹果,小易想购买尽量少的袋数方便携带。如果不能购买恰好n个苹果,小易将不会购买。
解法:
送分题,注意枚举态势
import java.util.Scanner;
public class Main{
static int n;
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
n = cin.nextInt();
cin.close();
for(int s = 0;s*6<=n;s++)
for(int e = 0;e*8<=n;e++)
if(e*8+s*6==n){
System.out.println(e+s);
return ;
}
System.out.println("-1");
}
}
8. A,B,C三个人是好朋友,每个人手里都有一些糖果,我们不知道他们每个人手上具体有多少个糖果,但是我们知道以下的信息:
A - B, B - C, A + B, B + C. 这四个数值.每个字母代表每个人所拥有的糖果数.
现在需要通过这四个数值计算出每个人手里有多少个糖果,即A,B,C。这里保证最多只有一组整数A,B,C满足所有题设条件。
解法:
解初中方程
import java.util.Scanner;
public class Main{
static int a,b,c,d,A,B,C;
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
a = cin.nextInt();
b = cin.nextInt();
c = cin.nextInt();
d = cin.nextInt();
cin.close();
B = (c-a)/2;
if(c-a<0||(c-a)%2==1||a+B<0||B-b<0||B-b!=d-B){
System.out.println("No");
return ;
}
A = a+B;
C = B-b;
System.out.println(A+" "+B+" "+C);
}
}
{1, 2, 1}, {15, 78, 78, 15} , {112} 是回文序列,
{1, 2, 2}, {15, 78, 87, 51} ,{112, 2, 11} 不是回文序列。
现在给出一个数字序列,允许使用一种转换操作:
选择任意两个相邻的数,然后从序列移除这两个数,并用这两个数字的和插入到这两个数之前的位置(只插入一个和)。
现在对于所给序列要求出最少需要多少次操作可以将其变成回文序列。
解法: 从两边往中间靠,不等的取较小数合并它的相邻数
public class Main{
static int n,ans;
static int a[] = new int[55];
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
n = cin.nextInt();
for(int i=0;i<n;i++)
if(cin.hasNextInt())
a[i] = cin.nextInt();
cin.close();
dfs(0,n-1);
System.out.println(ans);
}
public static void dfs(int i,int j){
while(a[i]==a[j]){
++i;
--j;
if(j<=i)return ;
}
if(a[i]<a[j]){
a[i+1]+=a[i];
++i;
}else {
a[j-1]+=a[j];
--j;
}
ans++;
dfs(i,j);
}
}
2. 小易有一个圆心在坐标原点的圆,小易知道圆的半径的平方。小易认为在圆上的点而且横纵坐标都是整数的点是优雅的,小易现在想寻找一个算法计算出优雅的点的个数,请你来帮帮他。
例如:半径的平方如果为25
优雅的点就有:(+/-3, +/-4), (+/-4, +/-3), (0, +/-5) (+/-5, 0),一共12个点。
解法: 枚举四分之一个圆,勾股定理判断整数,最后考虑4个和坐标轴交点是否满足
import java.util.Scanner;
public class Main{
static int R,r,e,max;
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
R = cin.nextInt();
r = (int)(Math.sqrt(R));
if(r*r==R){e=4;max=r-1;}
else max = r;
int T,t;
int ans=0;
for(int i=1;i<=max;i++){
T = R-i*i;
t = (int)Math.sqrt(T);
if(t*t==T){
++ans;
}
}
System.out.println(ans*4+e);
cin.close();
}
}
3. 小易来到了一条石板路前,每块石板上从1挨着编号为:1、2、3.......
这条石板路要根据特殊的规则才能前进:对于小易当前所在的编号为K的 石板,小易单次只能往前跳K的一个约数(不含1和K)步,即跳到K+X(X为K的一个非1和本身的约数)的位置。 小易当前处在编号为N的石板,他想跳到编号恰好为M的石板去,小易想知道最少需要跳跃几次可以到达。
例如:
N = 4,M = 24:
4->6->8->12->18->24
于是小易最少需要跳跃5次,就可以从4号石板跳到24号石板
解法: 广度搜索,这题卡了一下,记忆搜索没达到优化效果,直接取出所有素数就能达到优化效果
import java.util.LinkedList;
import java.util.Scanner;
class Step{
int val;
int step;
public Step(int v,int s){
val = v;
step = s;
}
}
public class Main{
static int m,n;
static int r[]=new int[100005];
static int prime[] = new int[100005];
static LinkedList<Step> list = new LinkedList<Step>();
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
m = cin.nextInt();
n = cin.nextInt();
cin.close();
list.add(new Step(m,0));
Step t;
init();
while(!list.isEmpty()){
t = list.poll();
if(t.val==n){
System.out.println(t.step);
return ;
}
if(prime[t.val]==1)
for(int j=2;j<=(int)Math.sqrt(t.val);j++)
if(t.val%j==0){
if(t.val+j<=n&&(0==r[t.val+j]||r[t.val+j]>t.step+1)){
list.add(new Step(t.val+j,t.step+1));
r[t.val+j]=t.step+1;
}
if(t.val+t.val/j<=n&&(0==r[t.val+t.val/j]||r[t.val+t.val/j]>t.step+1)){
list.add(new Step(t.val+t.val/j,t.step+1));
r[t.val+t.val/j]=t.step+1;
}
}
}
System.out.println(-1);
}
static void init(){
prime[2]=0;
for(int i=2;i<=100000;i++)
if(prime[i]==0){
for(int j=2;i*j<=100000;j++)
prime[i*j]=1;
}
}
}
4.一个只包含'A'、'B'和'C'的字符串,如果存在某一段长度为3的连续子串中恰好'A'、'B'和'C'各有一个,那么这个字符串就是纯净的,否则这个字符串就是暗黑的。例如:
BAACAACCBAAA 连续子串"CBA"中包含了'A','B','C'各一个,所以是纯净的字符串
AABBCCAABB 不存在一个长度为3的连续子串包含'A','B','C',所以是暗黑的字符串
你的任务就是计算出长度为n的字符串(只包含'A'、'B'和'C'),有多少个是暗黑的字符串。
解法: 简单递推, 方案数 = 当前添加字符位置的前两位相同方案数 + 前两位不同方案数
dp[i] = dp[i-2]* 3 + (dp[i-1]-dp[i-2])*2
dp[i-2]表示前两位相同 , *3表示可去任意字符
dp[i-1]-dp[i-2] 表示在i-1位置,总方案数-和前位相同方案数,结果为两位不同的方案数,*2表示可取2种字符
import java.util.Scanner;
class Step{
int val;
int step;
public Step(int v,int s){
val = v;
step = s;
}
}
public class Main{
static int n;
static long dp[] = new long [33];
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
n = cin.nextInt();
cin.close();
dp[0]=0;dp[1]=3;dp[2]=9;
for(int i=3;i<=n;i++)
dp[i]=(dp[i-1]-dp[i-2])*2+dp[i-2]*3;
System.out.println(dp
);
}
}5. 对于一个整数X,定义操作rev(X)为将X按数位翻转过来,并且去除掉前导0。例如:
如果 X = 123,则rev(X) = 321;
如果 X = 100,则rev(X) = 1.
现在给出整数x和y,要求rev(rev(x) + rev(y))为多少?
解法:送分题
import java.util.Scanner;
public class Main{
static int n;
static long dp[] = new long [33];
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
n = cin.nextInt();
cin.close();
dp[0]=0;dp[1]=3;dp[2]=9;
for(int i=3;i<=n;i++)
dp[i]=(dp[i-1]-dp[i-2])*2+dp[i-2]*3;
System.out.println(dp
);
}
}
6.小易是一个数论爱好者,并且对于一个数的奇数约数十分感兴趣。一天小易遇到这样一个问题: 定义函数f(x)为x最大的奇数约数,x为正整数。 例如:f(44) = 11.
现在给出一个N,需要求出 f(1) + f(2) + f(3).......f(N)
例如: N = 7
f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) = 1 + 1 + 3 + 1 + 5 + 3 + 7 = 21
小易计算这个问题遇到了困难,需要你来设计一个算法帮助他。
解法: 卡了很久, N/2^x 表示1-N中2^x的倍数的数的个数, 其实就是等差数列规模不断缩小
如 8:
8/2^0 : 1 3 5 7 9
8/2^1: 1 3
8/2^2: 1
8/2^3: 1
ans = 1+3+5+7+9 + 1+3 +1 +1
import java.util.Scanner;
public class Main{
static int n;
static long ans;
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
n = cin.nextInt();
cin.close();
ans+= add(n);
for(int i=1;(1<<i)<=n;i++){
ans+= add(n/(1<<i));
}
System.out.println(ans);
}
static long add(int n){
long x = n/2+((n%2==0)?0:1);
return x*x;
}
}
7. 小易去附近的商店买苹果,奸诈的商贩使用了捆绑交易,只提供6个每袋和8个每袋的包装(包装不可拆分)。 可是小易现在只想购买恰好n个苹果,小易想购买尽量少的袋数方便携带。如果不能购买恰好n个苹果,小易将不会购买。
解法:
送分题,注意枚举态势
import java.util.Scanner;
public class Main{
static int n;
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
n = cin.nextInt();
cin.close();
for(int s = 0;s*6<=n;s++)
for(int e = 0;e*8<=n;e++)
if(e*8+s*6==n){
System.out.println(e+s);
return ;
}
System.out.println("-1");
}
}
8. A,B,C三个人是好朋友,每个人手里都有一些糖果,我们不知道他们每个人手上具体有多少个糖果,但是我们知道以下的信息:
A - B, B - C, A + B, B + C. 这四个数值.每个字母代表每个人所拥有的糖果数.
现在需要通过这四个数值计算出每个人手里有多少个糖果,即A,B,C。这里保证最多只有一组整数A,B,C满足所有题设条件。
解法:
解初中方程
import java.util.Scanner;
public class Main{
static int a,b,c,d,A,B,C;
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
a = cin.nextInt();
b = cin.nextInt();
c = cin.nextInt();
d = cin.nextInt();
cin.close();
B = (c-a)/2;
if(c-a<0||(c-a)%2==1||a+B<0||B-b<0||B-b!=d-B){
System.out.println("No");
return ;
}
A = a+B;
C = B-b;
System.out.println(A+" "+B+" "+C);
}
}
相关文章推荐
- 【在线笔试题解题报告系列】网易2017校招内推笔试之编程题【持续更新】
- 牛客网-网易2017秋招编程题集合-解题思路及源码
- 【网易2017春招】涂棋盘 解题报告
- 网易2017秋招编程题集合
- 【网易2017春招】消除重复元素 解题报告
- 牛客网-网易2017春招笔试真题编程题集合-解题思路及源码
- 买苹果( 网易2017秋招编程题集合)
- 网易2017春招编程题集合
- 网易2017秋招编程题集合
- 【牛客网】网易2017秋招编程题集合
- 跳石板( 网易2017秋招编程题集合)
- 网易2017春招编程题:集合 [python]
- 网易2017秋招编程题集合
- 网易2017秋招编程题集合
- 网易2017秋招编程题集合--完全解析
- 【网易2017春招】奇怪的表达式求值 解题报告
- 【网易2017春招】赶去公司 解题报告
- 网易2017秋招编程题集合
- 牛客网-网易2018校招内推编程题集合-解题思路及源码
- 2017网易内推编程题(判断单词):解答代码