总结:三道编程题都还是比较简单的,但是我不停地花式犯错导致只对了第一道编程题(往事不堪回首,说好的细心呢?),看来是无缘面试了。。。
PS:有很多问题本来想在面试时说的,不料小错误不断,无缘面试。。。
①官方提供的简历模版在选择学校时并没有我们学校,用户体验不好
②官网底部的校招和社招链接没有实时更新,甚至链接2013年的信息网址。
③笔试题细节问题也有:选择题中println中输出有空格,而所给的选项只有一个错误选项含有空格,其余的没有按照格式输出;编程题所给的限制与结束后给定的限制不同,一定程度上会造成对错误原因的误判而从错误的方向调试。
1. 跑步
题目
小明同学喜欢体育锻炼,他常常去操场上跑步。跑道是一个圆形,在本题中,我们认为跑道是一个半径为
R
R
的圆形,设圆心的坐标为原点。
小明跑步的起点坐标为
(R,0)
(
R
,
0
)
,他沿着圆形跑道跑步,而且一直沿着一个方向跑步。回到家后,他查看了自己的计步器,计步器显示他跑步的总路程为
L
L
。
小明想知道自己结束跑步时的坐标,但是他忘记自己是沿着顺时针方向还是逆时针方向跑的了。他想知道在这两种情况下的答案分别是多少。
思路 - 几何
根据扇形周长公式可知:走过的角度(弧度制)
则可直接算出坐标:
①逆时针:(
R∗cos(angle),−R∗sin(angle)
R
∗
c
o
s
(
a
n
g
l
e
)
,
−
R
∗
s
i
n
(
a
n
g
l
e
)
)
②顺时针:(
R∗cos(angle),R∗sin(angle)
R
∗
c
o
s
(
a
n
g
l
e
)
,
R
∗
s
i
n
(
a
n
g
l
e
)
)
代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double l, r, x, y, angle;
while(input.hasNext()) {
l = input.nextDouble();
r = input.nextDouble();
angle = l / r;
x = r * Math.cos(angle);
y = r * Math.sin(angle);
System.out.printf("%.3f %.3f", x, -y);
System.out.println();
System.out.printf("%.3f %.3f", x, y);
System.out.println();
}
input.close();
}
}
2. 剪气球串
题目
小明买了一些彩色的气球用绳子串在一条线上,想要装饰房间,每个气球都染上了一种颜色,每个气球的形状都是各不相同的。
我们用1到9一共9个数字表示不同的颜色
我
们
用
1
到
9
一
共
9
个
数
字
表
示
不
同
的
颜
色
,如
12345
12345
则表示一串
5
5
个颜色各不相同的气球串。但小明希望得到不出现重复颜色的气球串,那么现在小明需要将这个气球串剪成多个较短的气球串,小明一共有多少种剪法?。
注意每种剪法需满足最后的子串中气球颜色各不相同(如果满足该条件,允许不剪,即保留原串)。两种剪法不同当且仅当存在一个位置,在一种剪法里剪开了,而在另一种中没剪开。详见样例分析。
思路 - DP
求方案数,很明显是 DP D P ,很容易就能想到常数为 9 9 的的做法,设 dp[i] d p [ i ] 表示前 i i 个气球能形成的方案数,,其中区间 [j,i] [ j , i ] 不含重复的气球,从后往前开始判断,最多循环 9 9 次。
清楚地记得测试时限时
1ms
1
m
s
,限制空间
128KB
128
K
B
,但是出来就变成限时
2000ms
2000
m
s
,限空间
128MB
128
M
B
了。。。
因为申请的是
Java开发工程师
J
a
v
a
开
发
工
程
师
,所以用
Java
J
a
v
a
写题(犯的第一个错误)。
虽然
Java
J
a
v
a
空间限制比较送,但是还是想按
C++
C
+
+
的空间限制做(犯的第二个错误),就取模只看最近的
10
10
个,导致下标要从
0
0
开始,然后各种下标中取模,又导致写搓了,结果很难看出错误,电脑用调试又比较卡,就用
println
p
r
i
n
t
l
n
大法。。。最终当然是没有调试流畅,导致没发现错误,惨败
结束后发现:把 vis[num[jj]] v i s [ n u m [ j j ] ] 写成 vis[jj] v i s [ j j ]
代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n, ii, jj;
int[] num = new int[11];
int[] dp = new int[11];
boolean[] vis = new boolean[11];
while(input.hasNext()) {
n = input.nextInt();
num[0] = input.nextInt();
dp[9] = dp[0] = 1;
for(int i = 1; i < n; ++i) {
for(int j = 1; j <= 9; ++j) {
vis[j] = false;
}
ii = i % 10;
num[ii] = input.nextInt();
vis[num[ii]] = true;
dp[i % 10] = dp[(i - 1) % 10];
for(int j = 1; j < 9 && i >= j; ++j) {
jj = (i - j) % 10;
if(vis[num[jj]]) {
break;
}
dp[ii] = dp[ii] + dp[(jj + 9) % 10];
if(dp[ii] >= 1000000007) {
dp[ii] -= 1000000007;
}
vis[num[jj]] = true;
}
}
System.out.printf("%d", dp[(n - 1) % 10]);
System.out.println();
}
input.close();
}
}
3. 分金子
题目
A、B
A
、
B
两伙马贼意外地在一片沙漠中发现了一处金矿,双方都想独占金矿,但各自的实力都不足以吞下对方,经过谈判后,双方同意用一个公平的方式来处理这片金矿。处理的规则如下:他们把整个金矿分成
n
n
段,由开始轮流从最左端或最右端占据一段,直到分完为止。
马贼
A
A
想提前知道他们能分到多少金子,因此请你帮忙计算他们最后各自拥有多少金子?(两伙马贼均会采取对己方有利的策略)
思路 - 区间DP
设表示先手在区间
[l,r]
[
l
,
r
]
最多能取的数的和,则状态转移方程为:
dp[l][r]=max(num[l]+dp[l+1][r],num[r]+dp[l][r−1])
d
p
[
l
]
[
r
]
=
m
a
x
(
n
u
m
[
l
]
+
d
p
[
l
+
1
]
[
r
]
,
n
u
m
[
r
]
+
d
p
[
l
]
[
r
−
1
]
)
最简单的区间 DP D P ,随手就写了一个记忆化搜索方式的,结果 TLE T L E ,由于当时第二题还没写,就先不管了,以为要 O(nlogn) O ( n l o g n ) 的解法才行。
结束后才发现递归返回时没有给 dp d p 赋值。。。(我一定是个“存盘退出”)
代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int T = input.nextInt(), kase = 0;
int n, ans;
int[] sum = new int[503];
int[][] dp = new int[503][503];
while(kase++ < T) {
n = input.nextInt();
sum[0] = 0;
for(int i = 1; i <= n; ++i) {
sum[i] = sum[i - 1] + input.nextInt();
for(int j = 1; j <= n; ++j) {
dp[i][j] = -1;
}
}
ans = getAns(sum, dp, 1, n);
System.out.printf("Case #%d: %d %d", kase, ans, sum[n] - ans);
System.out.println();
}
input.close();
}
private static int getAns(int[] sum, int[][] dp,int l, int r) {
if(dp[l][r] != -1) {
return dp[l][r];
}
if(l == r) {
return sum[r] - sum[l - 1];
}
return dp[l][r] = sum[r] - sum[l - 1] - Math.min(getAns(sum, dp, l + 1, r) , getAns(sum, dp, l, r - 1));
}
}