问题描述:

小扣注意到秋日市集上有一个创作黑白方格画的摊位。摊主给每个顾客提供一个固定在墙上的白色画板,画板不能转动。画板上有 n * n 的网格。绘画规则为,小扣可以选择任意多行以及任意多列的格子涂成黑色,所选行数、列数均可为 0。

小扣希望最终的成品上需要有 k 个黑色格子,请返回小扣共有多少种涂色方案。

注意:两个方案中任意一个相同位置的格子颜色不同,就视为不同的方案。

示例 1:

输入:n = 2, k = 2

输出:4

解释:一共有四种不同的方案:
第一种方案:涂第一列;
第二种方案:涂第二列;
第三种方案:涂第一行;
第四种方案:涂第二行。

示例 2:

输入:n = 2, k = 1

输出:0

解释:不可行,因为第一次涂色至少会涂两个黑格。

示例 3:

输入:n = 2, k = 4

输出:1

解释:共有 2*2=4 个格子,仅有一种涂色方案。

限制:

1 <= n <= 6
0 <= k <= n * n

解题思路:

假设完成k个格子的涂黑任务,需要涂i行j列才能完成,则只需遍历求出具体的i,j的值在排列组合便可。

 1 class Solution {
 2     public int paintingPlan(int n, int k) {
 3         //当全涂满和一个不涂的时候,都仅有一种涂色方案
 4         if(k==n*n||k==0){
 5             return 1;
 6         }
 7         //当所需要涂画的格子数超过了全部格子数,或小于一行的格子数时都无法完成
 8         else if(k<n||k>n*n){
 9             return 0;
10         }
11         else{
12             //定义行数i,列数j,涂色方案数m
13             int i=0,j=0,m=0;
14             //遍历所有可能
15             for(i=0;i<n;i++){
16                 for(j=0;j<n;j++){
17                     //当涂了i行j列时格子数为k
18                     if((n*(i+j)-j*i)==k){
19                         m=m+(fact(n)/(fact(i)*fact(n-i)))*(fact(n)/(fact(j)*fact(n-j)));
20                     }
21                     //如果超过则跳出本次循环
22                     else if((n*(i+j)-j*i)>k){
23                         break;
24                     }
25                 }
26             }
27             return m;
28         }
29     }
30     //计算阶乘
31     private int fact(int nums){
32         int result=1;
33         for(int i=1;i<=nums;i++){
34             result=result*i;
35         }
36         return result;
37     }
38 }

 

posted on 2021-03-25 16:05  wxcongajiayou  阅读(140)  评论(0)    收藏  举报