トップページに戻る
次の競技プログラミングの問題へ
前の競技プログラミングの問題へ
ABC-065-C Reconciled?
■■■問題■■■
すぬけ君は、犬をN匹と猿をM匹飼っています。
すぬけ君は、この N+M 匹を一列に並べようと思っています。
文字通り犬猿の仲の犬たちと猿たちを仲直りさせたいすぬけ君は、
犬同士、または猿同士が隣り合うところができないように並べようと思っています。
このような並べ方は何通りあるでしょうか。
犬と猿は 1000000007 以上の数を理解できないので、
並べ方の個数を 1000000007 で割ったあまりを求めてください。
ただし、犬同士、また猿同士は互いに区別します。
また、左右が反転しただけの列も異なる列とみなします。
■■■入力■■■
N M
●1 <= N,M <= 10万
■■■出力■■■
並べ方の個数を 1000000007 で割ったあまりを出力せよ。
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "Input1";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("2 2");
//8
//犬をそれぞれ A,B とし、猿をそれぞれ C,D とすると、
//ACBD,ADBC,BCAD,BDAC,CADB,CBDA,DACB,DBCA の8通りの並べ方があります。
}
else if (InputPattern == "Input2") {
WillReturn.Add("3 2");
//12
}
else if (InputPattern == "Input3") {
WillReturn.Add("1 8");
//0
}
else if (InputPattern == "Input4") {
WillReturn.Add("100000 100000");
//530123477
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
const long Hou = 1000000007;
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = InputList[0].Split(' ').Select(X => int.Parse(X)).ToArray();
int N = wkArr[0];
int M = wkArr[1];
long Answer = 0;
long InuCnt = DeriveKaijyou(N);
long SaruCnt = DeriveKaijyou(M);
//犬始まりの順列
if (N == M || N + 1 == M) {
Answer += (InuCnt * SaruCnt) % Hou;
Answer %= Hou;
}
//猿始まりの順列
if (M == N || M + 1 == N) {
Answer += (InuCnt * SaruCnt) % Hou;
Answer %= Hou;
}
Console.WriteLine(Answer);
}
//階乗を求める
static long DeriveKaijyou(int pVal)
{
long WillReturn = 1;
for (int I = 1; I <= pVal; I++) {
WillReturn *= I;
WillReturn %= Hou;
}
return WillReturn;
}
}
解説
犬始まりと猿始まりの順列の個数を求めて、足してます。