阿里内推算法岗位编程笔试题

算法岗是地图上色,相邻块颜色不同问题,类似以前奥数的五色地图。递推求公式可解。

###/填坑部分*****/

###题目表述:

一个圆分成n个扇形,用m种颜色上色,要求相邻两个颜色不同。求有多少种不同的方法。

###思路:

首先考虑一些奇怪的临界值

n=1:有m种可能。

n=2:有m(m-1)种可能。

m<2:并且n>2:毫无可能。

然后考虑正常情况

第一个扇面有m种可能,在不考虑最后一个和第一个扇面的颜色关系情况下,后面的n-1块都是有m-1种可能性。但这样得到的可能性是多的,接下来就是要考虑减去第一块和最后一块同色的情况。

当同色时候,其实可以把两个扇面融合,看成一个扇面,这是本题求解的关键。这样减去的部分就可以变成问题参数是(n-1,m)时得到的可能性。

递归表达式出来了:

###S(n,m) = m*(m-1)^(n-1) - S(n-1,m)

其实可以进一步运用高中数学中数列知识,把m看成常数,配一下项,变成等比数列,直接得到最后通式:

###Sn = (-1)^n * (m-1) + (m-1)^n

具体操作不展开了…因为我懒,并且打公式好烦。

代码如下:

#include 
#include 
using namespace std;
double digui(int n, int m){
    if(n==1)
        return m;
    if(n==2){
        if (m<2)
            return 0.0;
        return (double)m*(m-1);
     }
    return m*pow(double(m-1), double(n-1))-digui(n-1, m);
}
int main(){
	int N, M;
	cin >> N >> M;
	int ans = 0;
	ans=(int)digui(N,M);
	printf("%d", ans);
	return 0;
}

   
   
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

开发岗是求矩阵最短路径,DP思想,构建状态矩阵可解。
###/填坑部分*****/
###题目表述:
一行方格还是瓷砖n个,有m种颜色可以用来上色,每个格子上色的价格是不同(比如第一个上红色5元,第二个上红色3元)。要求相邻格子的颜色不同情况下,最小花费是多少。
输入格式:
n m
第一格填不同颜色的价格:a b c …(一共m行)



第n格…
比如:
3 3
12 10 8(给第一个格子上色,三种颜色的价格)
6 5 4
9 5 4
###思路:
第一眼以为和算法岗一样,后来仔细一看就发现天差地别。这是经典的DP,状态转移。
找不到题目了,拍照不清楚。。。
大概就是一个矩阵,里面都是正数,然后从最上面走到最下面最小cost是多少这种题目一样,只不过加了一个不能相邻格子走直线而已。

        

先挂题目

————————————————————————————————————————————————————————

光明小学的小朋友们要举行一年一度的接力跑大赛了,但是小朋友们却遇到了一个难题:设计接力跑大赛的线路,你能帮助他们完成这项工作么?
光明小学可以抽象成一张有N个节点的图,每两点间都有一条道路相连。光明小学的每个班都有M个学生,所以你要为他们设计出一条恰好经过M条边的路径。
光明小学的小朋友们希望全盘考虑所有的因素,所以你需要把任意两点间经过M条边的最短路径的距离输出出来以供参考。

你需要设计这样一个函数:
res[][] Solve( N, M, map[][]);
注意:map必然是N * N的二维数组,且map[i][j] == map[j][i],map[i][i] == 0,-1e8 <= map[i][j] <= 1e8。(道路全部是无向边,无自环)2 <= N <= 100, 2 <= M <= 1e6。要求时间复杂度控制在O(N^3*log(M))。

map数组表示了一张稠密图,其中任意两个不同节点i,j间都有一条边,边的长度为map[i][j]。N表示其中的节点数。
你要返回的数组也必然是一个N * N的二维数组,表示从i出发走到j,经过M条边的最短路径
你的路径中应考虑包含重复边的情况。

阿里内推算法岗位编程笔试题_第1张图片

阿里内推算法岗位编程笔试题_第2张图片

——————————————————————————————————————————————————————

题目特别长,加上有点紧张,光是读题目就花了很久的时间。泪流满面谨以此题纪念即将三挂阿里的我。

——————————————————————————————————————————————————————

思路有点类似与求和问题,牛客网上的一道题目https://www.nowcoder.com/practice/11cc498832db489786f8a03c3b67d02c?tpId=85&&tqId=29869&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking但不完全一样。有兴趣可以做做。

先挂代码吧。。。


   
   
   
   
  1. package ali;
  2. import java.util.Scanner;
  3. public class zhaolu {
  4. public static void main(String[] args) {
  5. Scanner input = new Scanner(System.in);
  6. int n = input.nextInt();
  7. int m = input.nextInt();
  8. long[][] map = new long[n][n];
  9. for ( int i = 0; i < n; i++) {
  10. for ( int j = 0; j < n; j++) {
  11. map[i][j] = input.nextLong();
  12. }
  13. }
  14. long[][] res = new long[n][n];
  15. for ( int i = 0; i < res.length; i++) {
  16. for ( int j = 0; j < res.length; j++) {
  17. res[i][j] = Integer.MAX_VALUE;
  18. }
  19. }
  20. for ( int i = 0; i < n; i++) {
  21. int nowrow = i;
  22. int nowcol = i;
  23. int distance = 0;
  24. solve(nowcol, m, map, res, distance, nowrow);
  25. }
  26. for ( int i = 0; i < res.length; i++) {
  27. for ( int j = 0; j < res.length; j++) {
  28. System.out.print(res[i][j] + " ");
  29. }
  30. System.out.println();
  31. }
  32. }
  33. public static void solve(int nowcol, int m, long[][] map, long[][] res, long distance, int nowrow) {
  34. if (m == 0) {
  35. if (distance < res[nowrow][nowcol]) {
  36. res[nowrow][nowcol] = distance;
  37. return;
  38. }
  39. return;
  40. }
  41. for ( int nextcol = 0; nextcol < map[ 0].length; nextcol++) {
  42. if (nowcol != nextcol) {
  43. solve(nextcol, m - 1, map, res, distance + map[nowcol][nextcol], nowrow);
  44. }
  45. }
  46. return;
  47. }
  48. }

其实就一个solve函数。

nowrow,记录当前是哪一个出发点,每一行可以对应一个出发点。

nowcol,记录当前走到了哪一个节点。

m,用来记录还需要走多少步。

res,记录最短路径的矩阵

distance,表示当前走的距离

跳出递归的条件是,m==0也就是走完了规定的步数,更改记录的条件是,当前这种走法比以前的走法都要短。

递归过程中下一步是不能与当前位置重合的。

突然发现没什么好讲的了……这题思路并不难,就是参数比较多,处理起来容易出错……

祝大家好运~我再去哭一会儿……

编程题共3道,貌似与其它岗位的小伙伴题目都不一样,本人遇到的难度较低。另外题面包含错别字以及描述不太清晰,值得吐槽。

第一题 最小整数

有一个32位整数n,试找一个最小整数m,使得m的每一位之积等于n,如果找不到这样的整数,输出0

分析可知,整数m的所有位均为2-9的整数,对n做质因数分解变形(每次从9-2取数字做整除),能成功分解证明可以找到合适的整数,然后对分解出来的数字进行排序,从小到大输出,未发现明显trick,1A


   
   
   
   
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #define LL long long
  8. using namespace std;
  9. LL m ,n;
  10. LL item[ 1000];
  11. LL cnt;
  12. int yinshufenjie(LL num){
  13. cnt = 0;
  14. LL i;
  15. LL temp = num;
  16. do{
  17. temp=num;
  18. for (i = 9;i >= 2 ;i--)
  19. {
  20. while (num != i)
  21. {
  22. if (num%i == 0)
  23. {
  24. item[cnt++] = i;
  25. num = num / i;
  26. }
  27. else break;
  28. }
  29. }
  30. } while(temp != num);
  31. if(num< 10){
  32. item[cnt++]=num;
  33. return 1;
  34. }
  35. else{
  36. return 0;
  37. }
  38. }
  39. int main()
  40. {
  41. LL m ,n;
  42. cin>>n;
  43. if(yinshufenjie(n)){
  44. sort(item,item+cnt);
  45. for( int i= 0;i
  46. cout<
  47. }
  48. cout<< endl;
  49. }
  50. else{
  51. cout<< "0"<< endl;
  52. }
  53. return 0;
  54. }

第二题  NTES子串判断

水题,判断是否存在目标顺序的字符


   
   
   
   
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #define LL long long
  7. using namespace std;
  8. int main(){
  9. int t;
  10. char s[ 101];
  11. char ntes[ 10]= "NTES\0";
  12. int len = strlen(ntes);
  13. cin>>t;
  14. while(t--){
  15. cin>>s;
  16. int cnt = 0;
  17. int l = strlen(s);
  18. for( int i= 0;i
  19. if(s[i]==ntes[cnt]){
  20. cnt++;
  21. }
  22. if(cnt>len){
  23. break;
  24. }
  25. }
  26. //cout<
  27. if(cnt == len){
  28. cout<< "yes"<< endl;
  29. }
  30. else{
  31. cout<< "no"<< endl;
  32. }
  33. }
  34. return 0;
  35. }
  36. /*
  37. 2
  38. STNETEDTS
  39. TSENSTE
  40. */

第三题 树的深度

给出n 和 n行,n代表树有n个节点,接下来的n行,每一行有两个数字,代表该节点的左右子节点是否存在,1为存在,-1为不存在。节点输入的顺序有序,第一组为根节点的左右子节点,求树的最大深度。

分析:已知节点有序,证明同样深度的节点顺序出现,从子节点信息也可以累加下一层有多少个节点,因此只需要遍历输入,统计当前层和下一层有多少节点,累加深度即可


   
   
   
   
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #define LL long long
  7. using namespace std;
  8. struct node{
  9. int left;
  10. int right;
  11. }tree[ 101];
  12. int main(){
  13. int n;
  14. cin>>n;
  15. int father[ 101];
  16. int left,right;
  17. int cp= 1;
  18. int nextp= 0;
  19. int dep = 1;
  20. for( int i= 0;i
  21. cp--;
  22. cin>>left>>right;
  23. if(left> 0){
  24. nextp+= 1;
  25. }
  26. if(right> 0){
  27. nextp+= 1;
  28. }
  29. if(cp== 0){
  30. cp=nextp;
  31. if(cp> 0){
  32. dep+= 1;
  33. }
  34. nextp= 0;
  35. }
  36. }
  37. cout<endl;
  38. return 0;
  39. }

 

你可能感兴趣的:(面试经验)