Parking Lot(思维+数学)

93 阅读2分钟

Problem - 630I - Codeforces

原文题面

image.png

题目描述

有四种类型的汽车,每类汽车数量不限。

现在需要从上述汽车中选择 2n22n-2 辆汽车并进行排列,要求存在连续排列且仅有 nn 个汽车为同一类型。

求最终可得到的方案数。

同一类型的汽车的不同排列视为一种方案。

输入格式

仅输入一行,为数字 n(3<=n<=30)n(3<=n<=30)

输出格式

仅输出一行,为最终的方案数。

题目分析

一开始我想的是先限定某一类型的汽车选择 nn 辆,然后再对剩下的三种类型进行数量的枚举,最终运用统计中排列组合的方法求得方案数。

后来发现排列枚举方案数的方法最高需要求到 30!30!,会狠狠的爆 longlonglonglong,而且与题目真实的含义不符合。

于是我们通过枚举每个位置有几种选择来统计方案数。

首先先选择一类汽车选择 nn 辆,由于这 nn 辆车需要连续排列,所以我们将其当作一辆汽车处理。然后通过分类讨论其在排列的两边或者中间位置,分别对剩下的位置进行枚举(因为这一类连续汽车只能有 nn 辆连续)。

最大方案数不会超过 4n14^{n-1},需要开 longlonglonglong

Accept代码

#include <bits/stdc++.h>
#define int long long

using namespace std;

signed main()
{
    int n; cin >> n;
    int m = n - 2;
    int res = 4 * (2 * 3 * pow(4, m - 1) + (m - 1) * 9 * pow(4, m - 2));
    if (n == 3) res = 24;
    printf("%lld\n", res);
    return 0;
}

注意事项

在第一次对结果进行输出时,出现了以下情况:

image.png

我们发现先定义答案在进行输出时对的,而直接将计算过程写在输出项中时错误的。

换用 cout 进行输出会发现输出的结果为科学计数法的形式。

经过网上查找可知:

printf() 在输出时不会进行类型转换,而 pow() 的返回值是一个 double 型的值。根据 doubleint 的储存原理差距,导致 printf() 输出的 int 值出现错误。

因此,要想得到正确的结果,我们可以将double型的值进行 强制类型转换,即如上述代码所示。