結果
| 問題 |
No.621 3 x N グリッド上のドミノの置き方の数
|
| コンテスト | |
| ユーザー |
kuuso1
|
| 提出日時 | 2017-12-21 22:44:01 |
| 言語 | C#(csc) (csc 3.9.0) |
| 結果 |
AC
|
| 実行時間 | 650 ms / 3,000 ms |
| コード長 | 5,434 bytes |
| コンパイル時間 | 2,727 ms |
| コンパイル使用メモリ | 116,172 KB |
| 実行使用メモリ | 31,364 KB |
| 最終ジャッジ日時 | 2024-12-17 22:52:54 |
| 合計ジャッジ時間 | 32,453 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 66 |
コンパイルメッセージ
Microsoft (R) Visual C# Compiler version 3.9.0-6.21124.20 (db94f4cc) Copyright (C) Microsoft Corporation. All rights reserved.
ソースコード
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
class TEST{
static void Main(){
Sol mySol =new Sol();
mySol.Solve();
}
}
class Sol{
const long mod = (long) 1e9 + 7;
public void Solve(){
if(N == 1){
Console.WriteLine(2);
return;
}
// B * A^(N-1) * v;
int NN = 1 << 6;
EdgeA = new bool[NN,NN];
EdgeB = new bool[NN,NN];
tot = 0;
int[] ar = new int[H * W];
dfs(ar, 0 , 1);
//Console.WriteLine(tot);
long[][] e0 = new long[NN][];
for(int i=0;i<NN;i++){
e0[i] = new long[NN];
e0[i][i] = 1;
}
Mat E = new Mat(e0);
long[][] a0 = new long[NN][];
for(int i=0;i<NN;i++){
a0[i] = new long[NN];
}
long[][] b0 = new long[NN][];
for(int i=0;i<NN;i++){
b0[i] = new long[NN];
}
for(int i=0;i<NN;i++){
for(int j=0;j<NN;j++){
if(EdgeA[i,j]) a0[j][i] = 1;
if(EdgeB[i,j]) b0[j][i] = 1;
}
}
Mat A = new Mat(a0);
Mat B = new Mat(b0);
//Console.WriteLine(A);
//Console.WriteLine(B);
long[] v = new long[NN];
v[NN-1] = 1;
long k = N - 1;
var x = A;
var ret = E;
while(k > 0){
if((k & 1) == 1){
ret *= x;
}
x *= x;
k>>=1;
}
var C = B * ret;
var Cv = C * v;
long ans = Cv.Sum() % mod; if(ans < 0) ans += mod;
Console.WriteLine(ans);
}
bool[,] EdgeA;
bool[,] EdgeB;
int tot;
int H = 3, W = 7;
void dfs(int[] ar, int now, int cnt){
if(now == H * W){
bool chk = true;
for(int i=0;i<H;i++){
for(int j=0;j<W;j++){
if(InRange(i + 1, 0, H) && ar[i * W + j] == 0 && ar[(i + 1) * W + j] == 0) chk = false;
if(InRange(j + 1, 0, W) && ar[i * W + j] == 0 && ar[i * W + j + 1] == 0) chk = false;
}
}
if(chk){
tot++;
for(int j=0;j+2<W;j++){
int[,] b = new int[3,3];
for(int ii=0;ii<3;ii++){
for(int jj=0;jj<2;jj++){
if(InRange(ii+1,0,3) && ar[ii * W + j + jj] != 0 && ar[(ii + 1) * W + j + jj] == ar[ii * W + j + jj]) b[ii,jj] = b[ii+1,jj] = 1;
if(InRange(jj+1,0,2) && ar[ii * W + j + jj] != 0 && ar[ii * W + j + jj + 1] == ar[ii * W + j + jj]) b[ii,jj] = b[ii,jj+1] = 1;
if(jj == 0 && ar[ii * W + j + jj] != 0) b[ii,jj] = 1;
}
}
int fr = 0;
for(int jj=0;jj<2;jj++){
for(int ii=0;ii<3;ii++){
int num = jj * 3 + ii;
if(b[ii,jj] == 1) fr |= (1 << num);
}
}
b = new int[3,3];
for(int ii=0;ii<3;ii++){
if(ar[ii * W + j + 1] != 0 && ar[ii * W + j + 1] == ar[ii * W + j + 2]) b[ii,1] = b[ii,2] = 1;
if(ii < 2 && ar[ii * W + j + 2] != 0 && ar[ii * W + j + 2] == ar[(ii + 1) * W + j + 2]) b[ii,2] = b[ii+1,2] = 1;
if(ar[ii * W + j + 1] != 0) b[ii,1] = 1;
}
int to = 0;
for(int jj=0;jj<2;jj++){
for(int ii=0;ii<3;ii++){
int num = jj * 3 + ii;
if(b[ii,jj + 1] == 1) to |= (1 << num);
}
}
//if(fr == 0x3F) Console.WriteLine(to);
//for(int ii=0;ii<3;ii++){ for(int jj=0;jj<3;jj++) Console.Write("{0}",b[ii,jj]);Console.WriteLine();}Console.WriteLine();
EdgeA[fr, to] = true;
if(j == W - 3) EdgeB[fr, to] = true;
}
}
return;
}
dfs(ar, now + 1, cnt);
int r = now / W, c = now % W;
if(InRange(r + 1, 0, H) && ar[now] == 0 && ar[now + W] == 0){
ar[now] = cnt; ar[now + W] = cnt;
dfs(ar, now + 1, cnt + 1);
ar[now] = 0; ar[now + W] = 0;
}
if(InRange(c + 1, 0, W) && ar[now] == 0 && ar[now + 1] == 0){
ar[now] = cnt; ar[now + 1] = cnt;
dfs(ar, now + 1, cnt + 1);
ar[now] = 0; ar[now + 1] = 0;
}
}
bool InRange(int t, int l, int r){
return l <= t && t < r;
}
long N;
public Sol(){
N = rl();
}
static String rs(){return Console.ReadLine();}
static int ri(){return int.Parse(Console.ReadLine());}
static long rl(){return long.Parse(Console.ReadLine());}
static double rd(){return double.Parse(Console.ReadLine());}
static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}
class Mat{
const int N = 1<<6;
long[][] m;
const long mod = (long) 1e9 + 7;
public Mat(){
m = new long[N][];
for(int i=0;i<N;i++) m[i] = new long[N];
}
public Mat(long[][] ma){
m = new long[N][];
for(int i=0;i<N;i++){
m[i] = new long[N];
for(int j=0;j<N;j++) m[i][j] = ma[i][j];
}
}
public static Mat operator * (Mat maa, Mat mab){
long[][] ma = maa.m;
long[][] mb = mab.m;
long[][] mc = new long[N][];
for(int i=0;i<N;i++) mc[i] = new long[N];
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
for(int k=0;k<N;k++){
mc[i][j] += ma[i][k] * mb[k][j];
mc[i][j] %= mod;
}
if(mc[i][j] < 0) mc[i][j] += mod;
}
}
return new Mat(mc);
}
public static long[] operator * (Mat maa, long[] v){
long[][] ma = maa.m;
var ret = new long[N];
for(int i=0;i<N;i++){
for(int k=0;k<N;k++){
ret[i] += ma[i][k] * v[k];
ret[i] %= mod;
}
if(ret[i] < 0) ret[i] %= mod;
}
return ret;
}
public override String ToString(){
var sb = new StringBuilder();
for(int i=0;i<N;i++) sb.AppendLine(String.Join(" ",m[i]));
return sb.ToString();
}
}
kuuso1