結果
問題 | No.663 セルオートマトンの逆操作 |
ユーザー | snow4726 |
提出日時 | 2018-03-16 21:20:36 |
言語 | C (gcc 12.3.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 6,096 bytes |
コンパイル時間 | 291 ms |
コンパイル使用メモリ | 30,336 KB |
実行使用メモリ | 8,736 KB |
最終ジャッジ日時 | 2024-06-01 09:34:21 |
合計ジャッジ時間 | 7,165 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,912 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 1 ms
5,376 KB |
testcase_03 | AC | 1 ms
5,376 KB |
testcase_04 | AC | 1 ms
5,376 KB |
testcase_05 | AC | 1 ms
5,376 KB |
testcase_06 | AC | 1 ms
5,376 KB |
testcase_07 | AC | 1 ms
6,940 KB |
testcase_08 | AC | 1 ms
5,376 KB |
testcase_09 | AC | 1 ms
5,376 KB |
testcase_10 | AC | 1 ms
5,376 KB |
testcase_11 | AC | 1 ms
5,376 KB |
testcase_12 | AC | 1 ms
5,376 KB |
testcase_13 | AC | 1 ms
5,376 KB |
testcase_14 | AC | 1 ms
5,376 KB |
testcase_15 | AC | 1 ms
5,376 KB |
testcase_16 | AC | 1 ms
5,376 KB |
testcase_17 | AC | 1 ms
5,376 KB |
testcase_18 | AC | 1 ms
5,376 KB |
testcase_19 | AC | 1 ms
5,376 KB |
testcase_20 | AC | 1 ms
5,376 KB |
testcase_21 | TLE | - |
testcase_22 | TLE | - |
testcase_23 | -- | - |
testcase_24 | -- | - |
testcase_25 | -- | - |
testcase_26 | -- | - |
testcase_27 | -- | - |
testcase_28 | -- | - |
ソースコード
/********************************************************** 一次元セルオートマトンルール110を1段目に適用した結果である2段目が 与えられるのであり得る1段目の種類数を出力するプログラム 入力:列数N、2段目のi列目の数値0か1 出力:2段目を生成できる1段目の種類数を10^9+7で割った余り **********************************************************/ #include<stdio.h> #include<stdlib.h> /* グローバル変数 */ int* first; /* 1段目の数列*/ int* second; /* 2段目の数列 */ int n; /* 列数N */ long long int saiki(int); /* 1段目の数列の種類数を求める再帰関数 */ int ismatch(int, int, int, int, int, int, int); /* 一次元セルオートマトンルールの上段の値の列毎の比較と一次元セルオートマトンの上段の値を仮定して決める関数 */ int main(){ int i; /* カウンタ */ long long int count; /* 1段目の数列の種類数 */ scanf("%d",&n); /* 列数Nの入力 */ first = (int*)calloc(n,sizeof(int)); /* 1段目の数列の領域確保 */ second = (int*)calloc(n,sizeof(int)); /* 2段目の数列の領域確保 */ for(i=0; i<n; i++){ scanf("%d",second+i); /* 2段目のi列目の数値の入力 */ } count = saiki(0); /* 再帰関数によって1段目の数列の種類数を求める */ printf("%lld\n",count%1000000007); /* 出力 */ return 0; } /********************************************************** 1段目の数列の種類数を求める再帰関数 引数:現在の列 返戻値:1段目の数列の種類数 **********************************************************/ long long int saiki(int stage){ long long int count = 0; /* 1段目の数列の種類数 */ int num1,num2,num3; /* 一次元セルオートマトンの上段の3つを指定する数列の列数番号 */ if( stage < n ){ /* 現在の列がn列目以下の時 */ if( stage == 0 ){ num1 = n - 1; /* 1列目は一次元セルオートマトンの上段の左の列数はn列目 */ }else{ num1 = stage - 1; /* 1列目以外は現在の列-1が一次元セルオートマトンの上段の左の列数 */ } if( stage == n - 1 ){ num3 = 0; /* n列目は一次元セルオートマトンの上段の右の列数は1列目 */ }else{ num3 = stage + 1; /* n列目以外は現在の列+1が一次元セルオートマトンの上段の右の列数 */ } num2 = stage; /* 一次元セルオートマトンの上段の真ん中の値の列数は現在の列 */ } if( stage == n ){ /* 現在の列がn+1列目の時はその数列は1段目の数列と見なされる */ count++; /* 1段目の数列の種類数をカウント*/ }else{ /* 探索中 */ if( second[stage] == 0 ){ /* 2段目の現在の列の数値が0の場合 */ if( ismatch(stage,num1,num2,num3,0,0,0) == 1 ) count += saiki(stage+1); /* 一次元セルオートマトンの上段が0,0,0の場合の比較、再帰 */ if( ismatch(stage,num1,num2,num3,1,0,0) == 1 ) count += saiki(stage+1); /* 一次元セルオートマトンの上段が1,0,0の場合の比較、再帰 */ if( ismatch(stage,num1,num2,num3,1,1,1) == 1 ) count += saiki(stage+1); /* 一次元セルオートマトンの上段が1,1,1の場合の比較、再帰 */ }else{ /* 2段目の現在の列の数値が1の場合 */ if( ismatch(stage,num1,num2,num3,0,0,1) == 1 ) count += saiki(stage+1); /* 一次元セルオートマトンの上段が0,0,1の場合の比較、再帰 */ if( ismatch(stage,num1,num2,num3,0,1,0) == 1 ) count += saiki(stage+1); /* 一次元セルオートマトンの上段が0,1,0の場合の比較、再帰 */ if( ismatch(stage,num1,num2,num3,0,1,1) == 1 ) count += saiki(stage+1); /* 一次元セルオートマトンの上段が0,1,1の場合の比較、再帰 */ if( ismatch(stage,num1,num2,num3,1,0,1) == 1 ) count += saiki(stage+1); /* 一次元セルオートマトンの上段が1,0,1の場合の比較、再帰 */ if( ismatch(stage,num1,num2,num3,1,1,0) == 1 ) count += saiki(stage+1); /* 一次元セルオートマトンの上段が1,1,0の場合の比較、再帰 */ } } return count; } /************************************************************************ 一次元セルオートマトンルールの上段の値の列毎の比較と 一次元セルオートマトンの上段の値を仮定して決める関数 引数:現在の列数、一つ前の列、現在の列、一つ後の列、一次元セルオートマトンの値3つ 返戻値:一次元セルオートマトンの上段の値の列毎の比較を行い全て等しいか否か ************************************************************************/ int ismatch(int stage, int num1, int num2, int num3, int i1, int i2, int i3){ int flag = 0; /* 一次元セルオートマトンの上段の値の列毎の比較に使うフラグ */ if( stage >= n - 2 ){ /* 2段目の現在の列がn-1かn列目の時 */ /* 一次元セルオートマトンの上段の値の列毎の比較 */ if( first[num1] == i1 && first[num2] == i2 && first[num3] == i3 ) flag = 1; }else if( stage != 0 ){ /* 2段目の現在の列が1列目以外の時 */ /* 一次元セルオートマトンの上段の値の列毎の比較 */ if( first[num1] == i1 && first[num2] == i2 ){ flag = 1; first[num3] = i3; /* 次の列の一次元セルオートマトンの上段の値を仮定する */ } }else{ /* 2段目の現在の列が1列目の時 */ /* 一次元セルオートマトンの上段の値3つ全てを仮定する */ first[num1] = i1; first[num2] = i2; first[num3] = i3; flag = 1; /* 1列目の時は無条件で判定OKとする */ } return flag; }