2021-03-06 阿里春招实习笔试算法题记录

题目一

可以参考 力扣1411
题目描述

小明现在手里有3种数字卡片,卡片上的数字分别为1,2,3,3种数字卡片每种都有若干张,他想将这些数字放入有一个N*3的方格中,每个方格中只能放入一张卡片,且要求相邻的上下左右方格不能放入同一种数字的卡片,现在问你有多少种可能的放入方案。

输入描述:

每个文件输入第一行输入一个整数T(1<=T<=500),代表有T组测试数据;
接下来T组,每一组输入一个整数n(1<=n<=100000);

输出描述:

对于每一组测试数据,输出一个答案代表可能的方案数,由于答案很大,请你对10^9+7取余;

示例1:

输入:
2
1
2
输出:
12
54

说明:

对于样例第一组放入1*3的方格中,可能的方案有:(1,2,1)、(2,1,2)、(3,1,2)、(1,2,3)、(2,1,3)、(3,1,3)、(1,3,1)、(2,3,1)、(3,2,1)、(1,3,2)、(2,3,2)、(3,2,3)


先上代码

import java.util.Scanner;

public class Main {
    
    
    private static long[][] dp = new long[10001][2];
    private static int now = 1;
    public static void main(String[] args) {
    
    
        dp[1][0] = 6L;
        dp[1][1] = 6L;
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        for(int i = 0 ; i < t ; i++){
    
    
            int n = sc.nextInt();
            if(n<=now){
    
    
                long res = (dp[n][0] + dp[n][1])%1000000007;
                int realRes = (int) res;
                System.out.println(realRes);
            } else {
    
    
                for(int j = now+1 ; j <= n ; j++){
    
    
                    dp[j][0] = (dp[j-1][0]*3 + dp[j-1][1]*2)%1000000007;
                    dp[j][1] = (dp[j-1][0]*2 + dp[j-1][1]*2)%1000000007;
                }
                long res = (dp[n][0] + dp[n][1])%1000000007;
                int realRes = (int) res;
                System.out.println(realRes);
                now = n;
            }
        }
    }
}

解题思路

第一想法是用dfs去做,但是肯定超时,上面也都提示了答案可能很大,所以dfs一个一个数肯定不行。

仔细分析题目给的示例输入,可以发现这样一个规律,2 * 3方格的方案都是由1 * 3方格方案拓展而来的!也就是说对于n * 3问题,我们只需要在n-1 * 3的方案基础上,对每个方案来考虑最后一排能扩展出几个方案即可

而对于每一排的方案我们可以将其分为两大类:
第一类:(1,2,1)、(2,1,2)、(3,1,3)、(1,3,1)、(2,3,2)、(3,2,3)。我们把这种称为ABA类
第二类:(3,1,2)、(1,2,3)、(2,1,3)、(2,3,1)、(3,2,1)、(1,3,2)。我们把这种称为ABC类

下面推导一下前一排和后一排的关系

  1. 如果前一排为ABA,那么后一排有5种可能,分别为 (C,A,C)、(B,A,B)、(B,C,B)、(B,A,C)、(C,A,B)。而这五种方案实际上就是 3种ABA 和 2种ABC ;

  2. 如果前一排为(A,B,C),那么后一排有4种可能,分别为(B,A,B)、(B,C,B)、(B,C,A)、(C,A,B)。而这四种方案实际上就是 2种ABA 和 2种ABC ;

所以我们假设n * 3问题为f(n) , ABA 方案数量为Xn,ABC 方案数量为Yn。

那么递推关系如下:
f(n+1) = Xn+1 + Yn+1;
Xn+1 = 3Xn + 2Yn;
Yn+1 = 2Xn + 2Yn;

最后可以用备忘录dp来记录之前计算过的问题,来防止重复计算,提高时间效率。
笔者为了防止溢出,用long类型来计算,并在每个地方都进行取余操作(应该不是很有必要)。


题目二

第二题是图论问题,不会。


总结

总体上来说,阿里笔试题难度不低,题目类型与CCF、ACM竞赛类题目类似,和力扣上的题目不是一个风格。之前只在力扣上刷题,感觉力扣只能锻炼一下算法题的解题思维。考前去牛客熟悉一下编程环境很重要,不然处理输入就要花费好长时间了。推荐大家把这一个小时的时间都用在尽力解一道题上面,不要前面做一下,做不出来又去做后面,大概率两道题都做出不(大牛应该不会看我的博客吧QAQ)。

最后即使一题都没做出来也没关系,阿里的笔试和素质测评好像只是一个参考,做不出来也有机会进到面试,好好准备面试吧!祝大家早日拿到offer!加油!

ps.有任何关于面试的问题可以在下面留言,或者想要阿里的内推方式也可以联系我哦!

猜你喜欢

转载自blog.csdn.net/weixin_43905212/article/details/114454963
今日推荐