Submission #434739
Source Code Expand
#include <cassert>
#include <functional>
#include <set>
#include <ctime>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdio>
#ifndef ONLINE_JUDGE //POJ
# include <complex>
# include <random>
# include <array>
# define mkt make_tuple
# define empb emplace_back
#endif
#ifdef _LOCAL
# include "for_local.h"
#endif
using namespace std;
typedef unsigned int uint; typedef long long ll; typedef unsigned long long ull;
#define repi(_I, _B, _E) for(int _I = (_B); (_I) < (_E); ++ (_I))
#define rep(_I, _N) for(int _I = 0; (_I) < (_N); ++ (_I))
#define mkp make_pair
#define all(_X) (_X).begin(), (_X).end()
inline int scani() { int n; scanf("%d", &n); return n; }
static ll const MOD = 1000000007;
static int const INF = 1<<29;
using pii = pair<int,int>;
int n; //不定セルの数
vector<int> dp;
//[index]=k: 位置 index に数字 k が書かれている
array<int, 5 * 5> board;
//[k]=index
array<int, 5 * 5> boardInv;
//[l]=index: l 番目の不定セルの位置 (昇順)
array<int, 5 * 5> pos;
//[index]=s: 位置 index の不定セルに対応する一元集合
array<int, 5 * 5> bitFromIndex;
//不定数字列と番兵
vector<int> flexnums;
int popcount(int s) {
int k = 0;
rep(i, 32) {
if ( s & (1 << i) ) ++k;
}
return k;
}
//状態 s で数字 k を書き込む直前に、(i,j) セルが書き込み済みか否か
bool written(int s, int k, int i, int j)
{
return (
//固定数字が書き込み済み
board[i * 5 + j] < k
//書き込み済みの不定セル
|| (s & bitFromIndex[i * 5 + j])
);
}
bool forbidden(int s, int k, int i, int j)
{
//両隣のうち片方だけが埋まっていたらダメ
//どちらかが枠外ならセーフ
if ( 1 <= i && i + 1 < 5 ) {
bool const up = written(s, k, i - 1, j);
bool const lo = written(s, k, i + 1, j);
if ( up ^ lo ) return true;
}
if ( 1 <= j && j + 1 < 5 ) {
bool const lef = written(s, k, i, j - 1);
bool const rig = written(s, k, i, j + 1);
if ( lef ^ rig ) return true;
}
return false;
}
//状態 s において l 番目の不定セルに数字 k が書き込まれた場合を加算
void update(int s, int k, int l) {
int const index = pos[l];
if ( forbidden(s, k, index / 5, index % 5) ) {
return;
}
int const t = s | (1 << l);
dp[t] = (dp[t] + dp[s]) % MOD;
}
bool verify(int s, int pc) {
int k = (pc == 0 ? 0 : flexnums[pc - 1] + 1);
for ( ; k < flexnums[pc]; ++k ) {
int const index = boardInv[k];
if ( forbidden(s, k, index / 5, index % 5) ) {
return false;
}
}
return true;
}
int solve() {
dp.resize(1 << n + 1, 0);
dp[0] = 1;
rep(s, 1 << n) {
int const pc = popcount(s);
//固定数字を順に書き込んでいく間に禁止状態を経由しないことを確認する
if ( !verify(s, pc) ) continue;
int const k = flexnums[pc]; //次に書く数字
rep(l, n) {
if ( s & (1 << l) ) continue; //配置済み
update(s, k, l);
}
}
return dp[(1 << n) - 1];
}
signed main() {
fill(all(boardInv), INF);
rep(i, 5 * 5) {
int k;
cin >> k; --k;
board[i] = (k >= 0 ? k : INF);
if ( k < 0 ) { //不定セル
bitFromIndex[i] = 1 << n;
pos[n] = i;
++n;
} else { //固定セル
boardInv[k] = i;
}
}
rep(k, 5 * 5) {
if ( boardInv[k] == INF ) {
flexnums.push_back(k);
}
}
flexnums.push_back(5 * 5);
cout << solve() << endl;
return 0;
}
Submission Info
Submission Time |
|
Task |
D - 25個の整数 |
User |
vain0 |
Language |
C++11 (GCC 4.9.2) |
Score |
100 |
Code Size |
3627 Byte |
Status |
AC |
Exec Time |
380 ms |
Memory |
8992 KB |
Judge Result
Set Name |
Sample |
Subtask1 |
Subtask2 |
Score / Max Score |
0 / 0 |
30 / 30 |
70 / 70 |
Status |
|
|
|
Set Name |
Test Cases |
Sample |
sample-01.txt, sample-02.txt, sample-03.txt, sample-04.txt |
Subtask1 |
sample-01.txt, sample-02.txt, sample-03.txt, sample-04.txt, test-1-01.txt, test-1-02.txt, test-1-03.txt, test-1-04.txt, test-1-05.txt, test-1-06.txt, test-1-07.txt, test-1-08.txt, test-1-09.txt, test-1-10.txt, test-1-11.txt, test-1-12.txt, test-1-13.txt, test-1-14.txt, test-1-15.txt |
Subtask2 |
sample-01.txt, sample-02.txt, sample-03.txt, sample-04.txt, test-1-01.txt, test-1-02.txt, test-1-03.txt, test-1-04.txt, test-1-05.txt, test-1-06.txt, test-1-07.txt, test-1-08.txt, test-1-09.txt, test-1-10.txt, test-1-11.txt, test-1-12.txt, test-1-13.txt, test-1-14.txt, test-1-15.txt, test-2-01.txt, test-2-02.txt, test-2-03.txt, test-2-04.txt, test-2-05.txt, test-2-06.txt, test-2-07.txt, test-2-08.txt, test-2-09.txt, test-2-10.txt |
Case Name |
Status |
Exec Time |
Memory |
sample-01.txt |
AC |
26 ms |
804 KB |
sample-02.txt |
AC |
23 ms |
928 KB |
sample-03.txt |
AC |
23 ms |
928 KB |
sample-04.txt |
AC |
25 ms |
800 KB |
test-1-01.txt |
AC |
24 ms |
924 KB |
test-1-02.txt |
AC |
22 ms |
928 KB |
test-1-03.txt |
AC |
23 ms |
796 KB |
test-1-04.txt |
AC |
24 ms |
932 KB |
test-1-05.txt |
AC |
24 ms |
924 KB |
test-1-06.txt |
AC |
23 ms |
804 KB |
test-1-07.txt |
AC |
23 ms |
924 KB |
test-1-08.txt |
AC |
23 ms |
928 KB |
test-1-09.txt |
AC |
23 ms |
924 KB |
test-1-10.txt |
AC |
24 ms |
796 KB |
test-1-11.txt |
AC |
25 ms |
800 KB |
test-1-12.txt |
AC |
26 ms |
704 KB |
test-1-13.txt |
AC |
24 ms |
804 KB |
test-1-14.txt |
AC |
24 ms |
924 KB |
test-1-15.txt |
AC |
24 ms |
676 KB |
test-2-01.txt |
AC |
32 ms |
1180 KB |
test-2-02.txt |
AC |
25 ms |
916 KB |
test-2-03.txt |
AC |
26 ms |
920 KB |
test-2-04.txt |
AC |
41 ms |
1308 KB |
test-2-05.txt |
AC |
61 ms |
1756 KB |
test-2-06.txt |
AC |
350 ms |
8984 KB |
test-2-07.txt |
AC |
380 ms |
8988 KB |
test-2-08.txt |
AC |
360 ms |
8992 KB |
test-2-09.txt |
AC |
346 ms |
8920 KB |
test-2-10.txt |
AC |
373 ms |
8984 KB |