Problem:
Problem D:
Weather Forecast
You are the God of Wind.
By moving a big cloud around, you can decide the weather: it invariably rains under the cloud,
and the sun shines everywhere else.
But you are a benign God: your goal is to give enough rain to every field in the countryside,
and sun to markets and festivals. Small humans, in their poor vocabulary, only describe this as
“weather forecast”.
You are in charge of a small country, called Paccimc. This country is constituted of 4 × 4 square
areas, denoted by their numbers.
Your cloud is of size 2 × 2, and may not cross the borders of the country.
You are given the schedule of markets and festivals in each area for a period of time.
On the first day of the period, it is raining in the central areas (6-7-10-11), independently of the
schedule.
On each of the following days, you may move your cloud by 1 or 2 squares in one of the four
cardinal directions (North, West, South, and East), or leave it in the same position. Diagonal
moves are not allowed. All moves occur at the beginning of the day.
You should not leave an area without rain for a full week (that is, you are allowed at most 6
consecutive days without rain). You don’t have to care about rain on days outside the period
you were given: i.e. you can assume it rains on the whole country the day before the period,
and the day after it finishes.
Input
The input is a sequence of data sets, followed by a terminating line containing only a zero.
A data set gives the number
N
of days (no more than 365) in the period on a single line, followed by
N
lines giving the schedule for markets and festivals. The
i
-th line gives the schedule for
the i-th day. It is composed of 16 numbers, either 0 or 1, 0 standing for a normal day, and 1 a
market or festival day. The numbers are separated by one or more spaces.
Output
The answer is a 0 or 1 on a single line for each data set, 1 if you can satisfy everybody, 0 if there
is no way to do it.
Sample Input
1
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
7
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 1 0 0 0 0 1 1 0 0 1
0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0
0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0
7
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0
0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0
0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
15
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0
0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0
1 0 0 1 1 0 0 0 0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0
0
Output for the Sample Input
0
1
0
1

Submitted solutions:

code_snippet: #include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<vector>
#include<stack>
#include<algorithm>
#include<queue>
#include<string>
#define OK 1
#define INF 2147483647
#define LINF 9223372036854775807LL
#define DINF 100000000
#define LL long long
using namespace std;
typedef struct
{
	int cnt[4][4];
}HNode;
vector<HNode>H[366][4][4];
int n,map[365][4][4];
int biao[4][4][4][2];
const int di[] = { 0, 0, 0, -1, -2, 0, 0, 1, 2 };
const int dj[] = { 0, -1, -2, 0, 0, 1, 2, 0, 0 };
bool dfs(int cur, int ci, int cj, int cnt[4][4]);
bool judge(int cur, int ci, int cj, int cnt[4][4]);

int main()
{
	int i,j,k,cnt[4][4];
	while (scanf("%d", &n) > 0)
	{
		if (n == 0) break;
		for (k = 0; k < n; k++)
		{
			for (i = 0; i < 4; i++)
			{
				for (j = 0; j < 4; j++) H[k][i][j].clear();
			}
		}
		for (k = 0; k < n; k++)
		{
			for (i = 0; i < 4; i++)
			{
				for (j = 0; j < 4; j++) scanf("%d", &map[k][i][j]);
			}
		}
		for (i = 0; i < 4; i++)
		{
			for (j = 0; j < 4; j++) cnt[i][j] = 1;
		}
		cnt[1][1] = cnt[1][2] = cnt[2][1] = cnt[2][2] = 0;
		judge(0, 1, 1, cnt);
		if (dfs(0, 1, 1, cnt) == true) printf("1\n");
		else printf("0\n");
	}
	return 0;
}

bool judge(int cur, int ci, int cj, int cnt[4][4])
{
	int k,j,i, len;
	bool flag = false;
	HNode e;
	for (k = 0, len = H[cur][ci][cj].size(); k < len; k++)
	{
		e = H[cur][ci][cj][k];
		flag = true;
		for (i = 0; i < 4; i++)
		{
			for (j = 0; j < 4; j++)
			{
				if (e.cnt[i][j] != cnt[i][j]) flag = false;
			}
		}
		if (flag == true) break;
	}
	if (flag == false)
	{
		for (i = 0; i < 4; i++)
		{
			for (j = 0; j < 4; j++) e.cnt[i][j] = cnt[i][j];
		}
		H[cur][ci][cj].push_back(e);
		return false;
	}
	else return true;
}

bool dfs(int cur,int ci,int cj,int cnt[4][4])
{
	int k,next_ci,next_cj,i,j,nextCnt[4][4];
	if (map[cur][ci][cj] == 1 || map[cur][ci][cj + 1] == 1 || map[cur][ci + 1][cj] == 1 || map[cur][ci + 1][cj + 1] == 1) return false;
	if (cur == n - 1)  return true;
	for (k = 0; k < 9; k++)
	{
		next_ci = ci + di[k];
		next_cj = cj + dj[k];
		if (next_ci < 0 || next_ci + 1 >= 4 || next_cj < 0 || next_cj + 1 >= 4) continue;
		memcpy(nextCnt, cnt, sizeof(nextCnt));
		for (i = 0; i < 4; i++)
		{
			for (j = 0; j < 4; j++) nextCnt[i][j]++;
		}
		nextCnt[next_ci][next_cj] = nextCnt[next_ci][next_cj + 1] = 0;
		nextCnt[next_ci + 1][next_cj] = nextCnt[next_ci + 1][next_cj + 1] = 0;
		bool flag = true;
		for (i = 0; i < 4; i++)  //判断下雨天数
		{
			for (j = 0; j < 4; j++)
			{
				if (nextCnt[i][j] == 7) flag = false;
			}
		}  
		if (flag == false) continue;
		if (judge(cur + 1, next_ci, next_cj, nextCnt) == true) continue;
		if (dfs(cur + 1, next_ci, next_cj, nextCnt) == true) return true;
 	}
	return false;
}
accuracy: 1
time_ms: 120
memory_kb: 17136
final_rank: 6

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int N;
vector<int> A(N);
vector<vector<int>> G(9);
map<int,bool> mp;

int encode(int K, int X, int Y, int D0, int D2, int D6, int D8) {
    return K*1000000+X*100000+Y*10000+D0*1000+D2*100+D6*10+D8;
}

bool DFS(int K, int X, int Y, int D0, int D2, int D6, int D8) {
    if (K == N) return true;
    if (D0 >= 7 || D2 >= 7 || D6 >= 7 || D8 >= 7) return false;
    if ((A[K] & (1<<(X*3+Y))) == 0) return false;
    int E = encode(K,X,Y,D0,D2,D6,D8);
    if (mp.count(E)) return mp[E];
    for (int Next : G[X*3+Y]) {
        int NX = Next / 3, NY = Next % 3;
        int N0 = D0+1, N2 = D2+1, N6 = D6+1, N8 = D8+1;
        if (Next == 0) N0 = 0;
        if (Next == 2) N2 = 0;
        if (Next == 6) N6 = 0;
        if (Next == 8) N8 = 0;
        if (DFS(K+1,NX,NY,N0,N2,N6,N8)) return mp[E] = true;
    }
    return mp[E] = false;
}

int main() {
    rep(i,0,3) {
        rep(j,0,3) {
            G[i*3+j].push_back(i*3+j);
            rep(k,0,3) {
                if (i != k) G[i*3+j].push_back(k*3+j);
                if (j != k) G[i*3+j].push_back(i*3+k);
            }
        }
    }
while(1) {
    mp.clear();
    cin >> N;
    if (N == 0) return 0;
    A.resize(N);
    rep(i,0,N) {
        vector<vector<int>> X(4,vector<int>(4));
        rep(j,0,4) rep(k,0,4) cin >> X[j][k];
        int B = 0;
        rep(j,0,3) {
            rep(k,0,3) {
                if (X[j][k] == 0 && X[j+1][k] == 0 && X[j][k+1] == 0 && X[j+1][k+1] == 0) B |= (1<<(j*3+k));
            }
        }
        A[i] = B;
    }
    cout << (DFS(0,1,1,1,1,1,1) ? 1 : 0) << endl;
}
}
accuracy: 1
time_ms: 20
memory_kb: 5160
final_rank: 2

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

int solve(int n) {
    using D = array<array<int, 4>, 4>;
    vector dp(3, vector(3, set<D>()));

    {
        bitset<16> a; {
            vector<int> a_ = in(16);
            for(int i : rep(16)) if(a_[i]) a[i] = 1;
        }
        bitset<16> b;
        b[5] = b[6] = b[9] = b[10] = 1;
        if((a & b) == 0) {
            D s = {
                1, 1, 1, 1,
                1, 0, 0, 1,
                1, 0, 0, 1,
                1, 1, 1, 1
            };
            dp[1][1].insert(s);
        }
    }

    for(int _  : rep(n - 1)) {
        bitset<16> a; {
            vector<int> a_ = in(16);
            for(int i : rep(16)) if(a_[i]) a[i] = 1;
        }
        vector nt(3, vector(3, set<D>()));
        for(int ci : rep(3)) for(int cj : rep(3)) {
            for(auto [di, dj] : vector<pair<int,int>>{{-2, 0}, {0, -2}, {-1, 0}, {0, -1}, {0, 0}, {+1, 0}, {0, +1}, {+2, 0}, {0, +2}}) {
                int ni = ci + di, nj = cj + dj;
                if(not(0 <= ni and ni + 1 < 4 and 0 <= nj and nj + 1 < 4)) continue;
                bitset<16> b;
                for(int i : rep(2)) for(int j : rep(2)) b[(ni + i) * 4 + (nj + j)] = 1;
                if(not((a & b) == 0)) continue;
                for(auto s : dp[ci][cj]) {
                    for(int i : rep(4)) for(int j : rep(4)) s[i][j] += 1;
                    for(int i : rep(2)) for(int j : rep(2)) s[ni + i][nj + j] = 0;
                    bool ok = [&] {
                        for(int i : rep(4)) for(int j : rep(4)) 
                            if(s[i][j] >= 7) return false;
                        return true;
                    }();
                    if(ok) nt[ni][nj].insert(s);
                }
            }
        }
        dp = move(nt);
    }
    for(int ci : rep(3)) for(int cj : rep(3)) if(not dp[ci][cj].empty()) return true;
    return false;
}

int main() {
    while(true) {
        int n = in();
        if(n == 0) return 0;
        print(solve(n));
    }
}
accuracy: 1
time_ms: 100
memory_kb: 3668
final_rank: 5

code_snippet: /**
 *    author:  otera
**/
#include<bits/stdc++.h>
using namespace std;

// #define int long long

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using int128_t = __int128_t;
#define repa(i, n) for(int i = 0; i < n; ++ i)
#define repb(i, a, b) for(int i = a; i < b; ++ i)
#define repc(i, a, b, c) for(int i = a; i < b; i += c)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define rep(...) overload4(__VA_ARGS__, repc, repb, repa)(__VA_ARGS__)
#define rep1a(i, n) for(int i = 0; i <= n; ++ i)
#define rep1b(i, a, b) for(int i = a; i <= b; ++ i)
#define rep1c(i, a, b, c) for(int i = a; i <= b; i += c)
#define rep1(...) overload4(__VA_ARGS__, rep1c, rep1b, rep1a)(__VA_ARGS__)
#define rev_repa(i, n) for(int i=n-1;i>=0;i--)
#define rev_repb(i, a, b) assert(a > b);for(int i=a;i>b;i--)
#define rev_rep(...) overload3(__VA_ARGS__, rev_repb, rev_repa)(__VA_ARGS__)
#define rev_rep1a(i, n) for(int i=n;i>=1;i--)
#define rev_rep1b(i, a, b) assert(a >= b);for(int i=a;i>=b;i--)
#define rev_rep1(...) overload3(__VA_ARGS__, rev_rep1b, rev_rep1a)(__VA_ARGS__)
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define eb emplace_back
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define rall(c) c.rbegin(), c.rend()
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define Sort(a) sort(all(a))
#define Rev(a) reverse(all(a))
#define Uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define si(c) (int)(c).size()
inline ll popcnt(ull a){ return __builtin_popcountll(a); }
#define kth_bit(x, k) ((x>>k)&1)
#define unless(A) if(!(A))
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll intpow(ll a, ll b, ll m) {ll ans = 1; while(b){ if(b & 1) (ans *= a) %= m; (a *= a) %= m; b /= 2; } return ans; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__;in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;in(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__;in(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__;in(__VA_ARGS__)
#define vec(type,name,...) vector<type>name(__VA_ARGS__)
#define VEC(type,name,size) vector<type>name(size);in(name)
#define vv(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define VV(type,name,h,w) vector<vector<type>>name(h,vector<type>(w));in(name)
#define vvv(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
template <class T> using vc = vector<T>;
template <class T> using vvc = vector<vc<T>>;
template <class T> using vvvc = vector<vvc<T>>;
template <class T> using vvvvc = vector<vvvc<T>>;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
template <class T, class U> using umap = unordered_map<T, U>;
template<class T> void scan(T& a){ cin >> a; }
template<class T> void scan(vector<T>& a){ for(auto&& i : a) scan(i); }
void in(){}
template <class Head, class... Tail> void in(Head& head, Tail&... tail){ scan(head); in(tail...); }
void print(){ cout << ' '; }
template<class T> void print(const T& a){ cout << a; }
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout << ' '; print(*i); } }
int out(){ cout << '\n'; return 0; }
template<class T> int out(const T& t){ print(t); cout << '\n'; return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); cout << ' '; out(tail...); return 0; }
#define CHOOSE(a) CHOOSE2 a
#define CHOOSE2(a0,a1,a2,a3,a4,x,...) x
#define debug_1(x1) cout<<#x1<<": "<<x1<<endl
#define debug_2(x1,x2) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<endl
#define debug_3(x1,x2,x3) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<endl
#define debug_4(x1,x2,x3,x4) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<", "#x4<<": "<<x4<<endl
#define debug_5(x1,x2,x3,x4,x5) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<", "#x4<<": "<<x4<<", "#x5<<": "<<x5<<endl
#ifdef DEBUG
#define debug(...) CHOOSE((__VA_ARGS__,debug_5,debug_4,debug_3,debug_2,debug_1,~))(__VA_ARGS__)
#define dump(...) { print(#__VA_ARGS__); print(":"); out(__VA_ARGS__); }
#else
#define debug(...)
#define dump(...)
#endif

struct io_setup {
    io_setup(int precision = 20) {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout << fixed << setprecision(precision);
    }
} io_setup_ {};

const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {1, 0, -1, 0};

const int M = 4;
const int D = 7;

void solve() {
    int n;
    while(cin >> n) {
        if(n == 0) break;
        VV(int, a, n, M * M);
        vector cnt(M, array<int, M>{0, 0, 0, 0});
        bool ans = 0;
        map<tuple<int, P, vector<array<int, M>>>, bool> memo;
        auto dfs = [&](auto &&dfs, int day, int x, int y) -> void {
            if(ans) return;
            if(day == n) {
                ans = 1;
                return;
            }
            if(memo.count(make_tuple(day, P{x, y}, cnt))) return;
            memo[make_tuple(day, P{x, y}, cnt)] = 1;
            bool ok = 1;
            auto ncnt = cnt;
            rep(i, M) {
                rep(j, M) {
                    if(0 <= (i - x) && (i - x) <= 1 && 0 <= (j - y) && (j - y) <= 1) {
                        // rain
                        if(a[day][i * M + j]) {
                            ok = 0;
                            break;
                        }
                        ncnt[i][j] = 0;
                    } else {
                        // not rain
                        ++ ncnt[i][j];
                        if(ncnt[i][j] >= 7) {
                            ok = 0;
                            break;
                        }
                    }
                }
            }
            if(!ok) {
                return;
            }
            swap(cnt, ncnt);
            rep(k, 4) {
                for(int _ = 1; _ <= 2; ++ _) {
                    int nx = x + _ * dx[k], ny = y + _ * dy[k];
                    if(0 <= nx && nx < 3 && 0 <= ny && ny < 3) {
                        dfs(dfs, day + 1, nx, ny);
                    }
                }
            }
            dfs(dfs, day + 1, x, y);
            swap(cnt, ncnt);
        };
        dfs(dfs, 0, 1, 1);
        out(ans);
    }
}

signed main() {
    int testcase = 1;
    // in(testcase);
    while(testcase--) solve();
    return 0;
}
accuracy: 1
time_ms: 720
memory_kb: 92020
final_rank: 20

code_snippet: #include <stdio.h>
#include <vector>
#include <set>
using namespace std;

int a[384][16], vis[16];
set<vector<int>> st[384];
vector<int> mv[16] = { {0, 1, 2, 4, 8}, {0, 1, 2, 5, 9}, {0, 1, 2, 6, 10}, {},
    {0, 4, 5, 6, 8}, {1, 4, 5, 6, 9}, {2, 4, 5, 6, 10}, {},
    {0, 4, 8, 9, 10}, {1, 5, 8, 9, 10}, {2, 6, 8, 9, 10}, {}, {}, {}, {}, {} };

int main(void) {
    int n, ok;
    vector<int> v;
    while (1) {
        scanf("%d", &n);
        if (n == 0) break;
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < 16; j++) {
                scanf("%d", &a[i][j]);
            }
        }
        if (a[1][5] || a[1][6] || a[1][9] || a[1][10]) {
            printf("0\n");
            continue;
        }
        
        st[1].insert({ 5, -1, -1, -1, -1, -1, -1 });
        for (int i = 1; i < n; i++) {
            for (auto& j : st[i]) {
                v = j;
                for (int k = 6; k > 0; k--) v[k] = v[k - 1];
                for (int k : mv[v[1]]) {
                    v[0] = k;
                    if (i < 6) ok = 1;
                    else {
                        ok = 1;
                        for (int l = 0; l < 7; l++) {
                            vis[v[l]] = 1;
                            vis[v[l] + 1] = 1;
                            vis[v[l] + 4] = 1;
                            vis[v[l] + 5] = 1;
                        }
                        for (int l = 0; l < 16; l++) {
                            if (!vis[l]) ok = 0;
                            vis[l] = 0;
                        }
                    }
                    if (a[i + 1][v[0]] || a[i + 1][v[0] + 1] || a[i + 1][v[0] + 4] || a[i + 1][v[0] + 5]) {
                        ok = 0;
                    }
                    if (ok) st[i + 1].insert(v);
                }
            }
        }

        if (st[n].size()) printf("1\n");
        else printf("0\n");

        for (int i = 0; i <= n; i++) st[i].clear();
    }
    return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 37844
final_rank: 16

code_snippet: #include <iostream>
#include <queue>
#include <vector>
#include <cstring>

using namespace std;

int counter[365][9][7][7][7][7];

int rain[9][16] {
    {1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0},
    {0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0},
    {0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0},
    {0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0},
    {0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0},
    {0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0},
    {0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0},
    {0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0},
    {0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1},
};

int adj[9][9] {
    {1,1,1,1,0,0,1,0,0},
    {1,1,1,0,1,0,0,1,0},
    {1,1,1,0,0,1,0,0,1},
    {1,0,0,1,1,1,1,0,0},
    {0,1,0,1,1,1,0,1,0},
    {0,0,1,1,1,1,0,0,1},
    {1,0,0,1,0,0,1,1,1},
    {0,1,0,0,1,0,1,1,1},
    {0,0,1,0,0,1,1,1,1},
};

struct X
{
    X(int d, int p, int ul, int ll, int ur, int lr) : day{d}, pos{p}, upleft{ul}, loleft{ll}, upright{ur}, loright{lr} {}
    int day;
    int pos;
    int upleft;
    int loleft;
    int upright;
    int loright;
};

bool check_pos(int p, vector<vector<int> > &event, int day) {
    for (int i=0; i<16; ++i)
        if (rain[p][i] == 1 && event[day][i] == 1) return false;
    return true;
}

bool check_day(int a, int b, int c, int d) {
    return !(a == 7 || b == 7 || c == 7 || d == 7);
}

int solve(int day, vector<vector<int> > &event) {
    int check = 0; // クリアできるか
    queue<X> Q;
    X init(0,4,1,1,1,1);
    if (!check_pos(4, event, 0)) return 0;
    Q.push(init);
    while (!Q.empty()) {
        X pick = Q.front();
        Q.pop();
        for(int i=0; i<9; ++i) {
            if (adj[pick.pos][i] == 1) {
                X c(pick.day+1,i,pick.upleft+1,pick.loleft+1,pick.upright+1,pick.loright+1);
                if (i == 0) c.upleft = 0; else if (i == 2) c.upright = 0; else if (i == 6) c.loleft = 0; else if (i == 8) c.loright = 0;
                if (check_pos(i, event, c.day) && check_day(c.upleft, c.loleft, c.upright, c.loright)) {
                    if (c.day == day-1) {
                        check = 1;
                        goto label;
                    } else {
                        if (counter[c.day][c.pos][c.upleft][c.loleft][c.upright][c.loright] == 0) {
                            Q.push(c);
                            counter[c.day][c.pos][c.upleft][c.loleft][c.upright][c.loright] += 1;
                        }
                    }
                }
            }
        }
    }
    label: ;
    return check;
}

int main() {
    int total;
    while (cin >> total && total > 0) {
        vector<vector<int> > event(total, vector<int>(16));
        for (int i=0; i<total; ++i) {
            for (int j=0; j<16; ++j) {
            cin >> event[i][j];
            }
        }
        memset(counter, 0, sizeof(counter));
        int ans = solve(total, event);
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 40
memory_kb: 33992
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define ALL(x) x.begin(), x.end()

bool dp[370][3][3][7][7][7][7][16];
bool a[370][4][4];
bool ok[3][3];

const int dx[9] = {2, 1, -1, -2, 0, 0, 0, 0, 0};
const int dy[9] = {0, 0, 0, 0, 0, 2, 1, -1, -2};

void solve(int N) {
    rep(i, N) rep(x, 3) rep(y, 3) rep(a1, 7) rep(a2, 7) rep(a3, 7) rep(a4, 7) rep(k, 16) dp[i][x][y][a1][a2][a3][a4][k] = false;
    rep(i, N) rep(x, 4) rep(y, 4) cin >> a[i][x][y];
    if (a[0][1][1] == true || a[0][1][2] == true || a[0][2][1] == true || a[0][2][2] == true) {
        cout << 0 << '\n';
        return;
    }
    dp[0][1][1][1][1][1][1][0] = true;
    for (int i = 1; i < N; i++) {
        rep(cx, 3) rep(cy, 3) {
            if (a[i][cx][cy] == true || a[i][cx][cy + 1] == true || a[i][cx + 1][cy] == true || a[i][cx + 1][cy + 1] == true)
                ok[cx][cy] = false;
            else
                ok[cx][cy] = true;
        }
        rep(cx, 3) rep(cy, 3) rep(a1, 7) rep(a2, 7) rep(a3, 7) rep(a4, 7) rep(b, 16) {
            if (dp[i - 1][cx][cy][a1][a2][a3][a4][b] == false) continue;
            // 遷移
            rep(k, 9) {
                int nx = cx + dx[k], ny = cy + dy[k];
                if (!(0 <= nx && nx < 3 && 0 <= ny && ny < 3)) continue;
                if (ok[nx][ny] == false) continue;
                int na1 = a1 + 1, na2 = a2 + 1, na3 = a3 + 1, na4 = a4 + 1, nb = b;
                if (nx == 0 && ny == 0) na1 = 0, nb |= 1;
                if (nx == 0 && ny == 2) na2 = 0, nb |= 2;
                if (nx == 2 && ny == 0) na3 = 0, nb |= 4;
                if (nx == 2 && ny == 2) na4 = 0, nb |= 8;
                if (na1 > 6) continue;
                if (na2 > 6) continue;
                if (na3 > 6) continue;
                if (na4 > 6) continue;
                dp[i][nx][ny][na1][na2][na3][na4][nb] = true;
            }
        }
    }
    rep(cx, 3) rep(cy, 3) rep(a1, 7) rep(a2, 7) rep(a3, 7) rep(a4, 7) {
        if (dp[N - 1][cx][cy][a1][a2][a3][a4][15] == true) {
            cout << 1 << '\n';
            return;
        }
    }
    cout << 0 << '\n';
    return;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int N;
    while (cin >> N, N) solve(N);
    return 0;
}
accuracy: 1
time_ms: 490
memory_kb: 128228
final_rank: 19

code_snippet: #include <iostream>
#include <algorithm>
#include <queue>
#include <tuple>
#include <cstring>
using namespace std;

const int MAX_N = 370;
const int AREA_NUM = 16;
const int dx[] = {0, 1, 0, -1, 0, 2, 0, -2, 0};
const int dy[] = {0, 0, -1, 0, 1, 0, -2, 0, 2};
const int ax[] = {0, 1, 0, 1};
const int ay[] = {0, 0, 1, 1};
int cache[MAX_N][3][3][7][7][7][7];

int need_sun[MAX_N][AREA_NUM];

struct State
{
    int x;
    int y;
    int t;
    int A;
    int B;
    int C;
    int D;
};

bool check_border(int x, int y)
{
    return ((0 <= x) && (x < 4) && (0 <= y) && (y < 4));
}

bool check_pos_and_specialday(int left_x, int top_y, int t)
{
    int right_x = left_x + 1;
    int bottom_y = top_y + 1;
    if (check_border(left_x, top_y) &&
        check_border(right_x, bottom_y))
        return (need_sun[t][left_x + top_y * 4] == 0) &&
               (need_sun[t][left_x + bottom_y * 4] == 0) &&
               (need_sun[t][right_x + top_y * 4] == 0) &&
               (need_sun[t][right_x + bottom_y * 4] == 0);
    else
        return false;
}

bool check_dry(State state)
{
    return state.A < 7 && state.B < 7 && state.C < 7 && state.D < 7;
}

State update_state(State state, int nx, int ny)
{
    State new_state = {nx, ny, state.t + 1,
                       state.A + 1, state.B + 1,
                       state.C + 1, state.D + 1};
    int idx = 0;
    for (int i = 0; i < 4; i++)
    {
        idx = nx + ax[i] + (ny + ay[i]) * 4;
        if (idx == 0)
            new_state.A = 0;
        else if (idx == 3)
            new_state.B = 0;
        else if (idx == 12)
            new_state.C = 0;
        else if (idx == 15)
            new_state.D = 0;
    }
    return new_state;
}

int solve(int N, int sx, int sy)
{
    int nx, ny, t;

    //左上のx座標・左上のy座標・何日目か・マス1の雨が降っていない期間
    queue<State> que;
    State init_state = {sx, sy, 0, 1, 1, 1, 1};

    bool last_day = false;
    que.push(init_state);
    while (!que.empty())
    {
        State state = que.front();
        que.pop();

        if (cache[state.t][state.x][state.y][state.A][state.B][state.C][state.D]++)
            continue;
        for (int i = 0; i < 9; i++)
        {
            nx = state.x + dx[i];
            ny = state.y + dy[i];
            t = state.t;
            if (t == N - 1)
            {
                last_day = true;
                break;
            }
            State new_state = update_state(state, nx, ny);
            if (check_dry(new_state) && check_pos_and_specialday(nx, ny, t + 1))
                que.push(new_state);
        }
    }

    if (last_day)
        return 1;
    else
        return 0;
}

int main()
{
    int N;
    while (cin >> N)
    {
        if (N == 0)
            break;

        for (int i = 0; i < N; i++)
            for (int j = 0; j < AREA_NUM; j++)
                cin >> need_sun[i][j];

        memset(cache, 0, sizeof(cache));
        int ans = solve(N, 1, 1);
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 34656
final_rank: 13

code_snippet: #include <algorithm>
#include <iostream>
#include <tuple>
#include <set>
#include <vector>
#include <queue>
using namespace std;

int n;
int cover[3][3];
int schedule[365];
int dx[3][3][5];
int dy[3][3][5];
// {四隅の連続して雨の降っていない日数、雲のx座標、雲のy座標、日付}
using State = tuple<int, int, int, int, int, int, int>;
set<State> used;

int solve() {
    used.clear();
    for(int i = 0; i < n; i++) {
        schedule[i] = 0;
        for(int j = 0; j < 16; j++) {
            int x; cin >> x;
            schedule[i] += x << j;
        }
    }
    // bit演算で重なりを判定
    if(cover[1][1] & schedule[0]) return 0;
    queue<State> q;
    q.push({1, 1, 1, 1, 1, 1, 0});
    while(!q.empty()) {
        auto now = q.front();
        q.pop();
        int c0 = get<0>(now), c1 = get<1>(now), c2 = get<2>(now), c3 = get<3>(now),
            x =  get<4>(now), y  = get<5>(now), d  = get<6>(now);
        if(d == n-1) return 1;
        c0++; c1++; c2++; c3++;
        for(int i = 0; i < 5; i++) {
            int nx = x + dx[x][y][i], ny = y + dy[x][y][i];
            // markets and festivals と重なっていないか
            if((cover[nx][ny]&schedule[d+1]) == 0) {
                State nxt = make_tuple(c0, c1, c2, c3, nx, ny, d+1);
                // 雨を降らしたときの日数のリセット
                if(nx == 0 && ny == 0) {
                    get<0>(nxt) = 0;
                } else if(nx == 0 && ny == 2) {
                    get<1>(nxt) = 0;
                } else if(nx == 2 && ny == 0) {
                    get<2>(nxt) = 0;
                } else if(nx == 2 && ny == 2) {
                    get<3>(nxt) = 0;
                }
                // 雨を連続で降らせていない場所がないか
                if(!used.count(nxt) &&
                    get<0>(nxt) != 7 && get<1>(nxt) != 7 &&
                    get<2>(nxt) != 7 && get<3>(nxt) != 7) {
                    q.push(nxt);
                    used.insert(nxt);
                }
            }
        }
    }
    return 0;
}

int main() {
    // 雲の遷移、雲がカバーしている位置の前計算
    // bit演算によって位置を管理することで高速化している
    // 以下のように番号を振り、雲がいるときは cover について番号のbitを立てる
    // 0   1   2   3
    // 4   5   6   7
    // 8   9   10  11
    // 12  13  14  15
    for(int i = 0; i < 3; i++) {
        for(int j = 0; j < 3; j++) {
            for(int ii = 0; ii < 2; ii++) {
                for(int jj = 0; jj < 2; jj++) {
                    cover[i][j] += 1 << ((i + ii) * 4 + (j + jj));
                }
            }
            for(int k = 1; k < 3; k++) {
                dx[i][j][k  ] = (i + k) % 3 - i;
                dy[i][j][k+2] = (j + k) % 3 - j;
            }
        }
    }
    vector<int> ans;
    while(1) {
        cin >> n;
        if(n == 0) break;
        ans.push_back(solve());
    }
    for(auto &i : ans) cout << i << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 7796
final_rank: 4

code_snippet: #include <algorithm>
#include <iostream>
#include <tuple>
#include <set>
#include <vector>
#include <queue>
using namespace std;

int n;
int cover[3][3];
int schedule[365];
int dx[3][3][5];
int dy[3][3][5];
using State = tuple<int, int, int, int, int, int, int>;
set<State> used;

int solve() {
    used.clear();
    for(int i = 0; i < n; i++) {
        schedule[i] = 0;
        for(int j = 0; j < 16; j++) {
            int x; cin >> x;
            schedule[i] += x << j;
        }
    }
    if(cover[1][1] & schedule[0]) return 0;
    queue<State> q;
    q.push({1, 1, 1, 1, 1, 1, 0});
    while(!q.empty()) {
        auto now = q.front();
        q.pop();
        int c0 = get<0>(now), c1 = get<1>(now), c2 = get<2>(now), c3 = get<3>(now),
            x =  get<4>(now), y  = get<5>(now), d  = get<6>(now);
        if(d == n-1) return 1;
        c0++; c1++; c2++; c3++;
        for(int i = 0; i < 5; i++) {
            int nx = x + dx[x][y][i], ny = y + dy[x][y][i];
            if((cover[nx][ny]&schedule[d+1]) == 0) {
                // cerr << x << " " << y << " " << nx << " " << ny << endl;
                State nxt = make_tuple(c0, c1, c2, c3, nx, ny, d+1);
                if(nx == 0 && ny == 0) {
                    get<0>(nxt) = 0;
                } else if(nx == 0 && ny == 2) {
                    get<1>(nxt) = 0;
                } else if(nx == 2 && ny == 0) {
                    get<2>(nxt) = 0;
                } else if(nx == 2 && ny == 2) {
                    get<3>(nxt) = 0;
                }
                if(!used.count(nxt) &&
                   get<0>(nxt) != 7 && get<1>(nxt) != 7 &&
                    get<2>(nxt) != 7 && get<3>(nxt) != 7) {
                    q.push(nxt);
                    used.insert(nxt);
                }
            }
        }
    }
    return 0;
}

int main() {
    for(int i = 0; i < 3; i++) {
        for(int j = 0; j < 3; j++) {
            for(int ii = 0; ii < 2; ii++) {
                for(int jj = 0; jj < 2; jj++) {
                    cover[i][j] += 1 << ((i + ii) * 4 + (j + jj));
                }
            }
            for(int k = 1; k < 3; k++) {
                dx[i][j][k  ] = (i + k) % 3 - i;
                dy[i][j][k+2] = (j + k) % 3 - j;
            }
        }
    }
    vector<int> ans;
    while(1) {
        cin >> n;
        if(n == 0) break;
        ans.push_back(solve());
    }
    for(auto &i : ans) cout << i << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 7748
final_rank: 3

code_snippet: /*
https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1243

現在の雲の左上の座標・何日目か・1,4,13,16番のセルが何日間連続で雨が降っていないかという情報を
クラスStateで保存する。方針としては幅優先探索を可能な限り行っていき、最終日まで条件を満たしながら
雲を動かしてけるかを確かめる。この時同じ状態を何度も探索することを防ぐために、cacheを用いている。

cacheを使うことを中々思いつかず、計算時間の問題を解決するのに時間がかかった。結局1時間程
かかってしまった。
 */

#include <iostream>
#include <algorithm>
#include <queue>
#include <tuple>
#include <cstring>
using namespace std;

const int MAX_N = 370;
const int AREA_NUM = 16;
const int dx[] = {0, 1, 0, -1, 0, 2, 0, -2, 0};
const int dy[] = {0, 0, -1, 0, 1, 0, -2, 0, 2};
const int ax[] = {0, 1, 0, 1};
const int ay[] = {0, 0, 1, 1};
int cache[MAX_N][3][3][7][7][7][7];

int need_sun[MAX_N][AREA_NUM];

struct State
{
    int x;
    int y;
    int t;
    int A;
    int B;
    int C;
    int D;
};

bool check_border(int x, int y)
{
    return ((0 <= x) && (x < 4) && (0 <= y) && (y < 4));
}

bool check_pos_and_specialday(int left_x, int top_y, int t)
{
    int right_x = left_x + 1;
    int bottom_y = top_y + 1;
    if (check_border(left_x, top_y) &&
        check_border(right_x, bottom_y))
        return (need_sun[t][left_x + top_y * 4] == 0) &&
               (need_sun[t][left_x + bottom_y * 4] == 0) &&
               (need_sun[t][right_x + top_y * 4] == 0) &&
               (need_sun[t][right_x + bottom_y * 4] == 0);
    else
        return false;
}

bool check_dry(State state)
{
    return state.A < 7 && state.B < 7 && state.C < 7 && state.D < 7;
}

State update_state(State state, int nx, int ny)
{
    State new_state = {nx, ny, state.t + 1,
                       state.A + 1, state.B + 1,
                       state.C + 1, state.D + 1};
    int idx = 0;
    for (int i = 0; i < 4; i++)
    {
        idx = nx + ax[i] + (ny + ay[i]) * 4;
        if (idx == 0)
            new_state.A = 0;
        else if (idx == 3)
            new_state.B = 0;
        else if (idx == 12)
            new_state.C = 0;
        else if (idx == 15)
            new_state.D = 0;
    }
    return new_state;
}

int solve(int N, int sx, int sy)
{
    int nx, ny, t;

    //左上のx座標・左上のy座標・何日目か・マス1の雨が降っていない期間
    queue<State> que;
    State init_state = {sx, sy, 0, 1, 1, 1, 1};

    bool last_day = false;
    que.push(init_state);
    while (!que.empty())
    {
        State state = que.front();
        que.pop();

        if (cache[state.t][state.x][state.y][state.A][state.B][state.C][state.D]++)
            continue;
        for (int i = 0; i < 9; i++)
        {
            nx = state.x + dx[i];
            ny = state.y + dy[i];
            t = state.t;
            if (t == N - 1)
            {
                last_day = true;
                break;
            }
            State new_state = update_state(state, nx, ny);
            if (check_dry(new_state) && check_pos_and_specialday(nx, ny, t + 1))
                que.push(new_state);
        }
    }

    if (last_day)
        return 1;
    else
        return 0;
}

int main()
{
    int N;
    while (cin >> N)
    {
        if (N == 0)
            break;

        for (int i = 0; i < N; i++)
            for (int j = 0; j < AREA_NUM; j++)
                cin >> need_sun[i][j];

        memset(cache, 0, sizeof(cache));
        int ans = solve(N, 1, 1);
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 40
memory_kb: 34644
final_rank: 9

code_snippet: #include <iostream>
#include <algorithm>
#include <queue>
#include <tuple>
#include <cstring>
using namespace std;

const int MAX_N = 370;
const int AREA_NUM = 16;
const int dx[] = {0, 1, 0, -1, 0, 2, 0, -2, 0};
const int dy[] = {0, 0, -1, 0, 1, 0, -2, 0, 2};
const int ax[] = {0, 1, 0, 1};
const int ay[] = {0, 0, 1, 1};
int cache[MAX_N][3][3][7][7][7][7];

int need_sun[MAX_N][AREA_NUM];

struct Info
{
    int x;
    int y;
    int t;
    int A;
    int B;
    int C;
    int D;
};

bool check_border(int x, int y)
{
    return ((0 <= x) && (x < 4) && (0 <= y) && (y < 4));
}

bool check_pos_and_specialday(int left_x, int top_y, int t)
{
    int right_x = left_x + 1;
    int bottom_y = top_y + 1;
    if (check_border(left_x, top_y) &&
        check_border(right_x, bottom_y))
        return (need_sun[t][left_x + top_y * 4] == 0) &&
               (need_sun[t][left_x + bottom_y * 4] == 0) &&
               (need_sun[t][right_x + top_y * 4] == 0) &&
               (need_sun[t][right_x + bottom_y * 4] == 0);
    else
        return false;
}

bool check_dry(Info info)
{
    return info.A < 7 && info.B < 7 && info.C < 7 && info.D < 7;
}

Info update_info(Info info, int nx, int ny)
{
    Info new_info = {nx, ny, info.t + 1,
                     info.A + 1, info.B + 1,
                     info.C + 1, info.D + 1};
    int idx = 0;
    for (int i = 0; i < 4; i++)
    {
        idx = nx + ax[i] + (ny + ay[i]) * 4;
        if (idx == 0)
            new_info.A = 0;
        else if (idx == 3)
            new_info.B = 0;
        else if (idx == 12)
            new_info.C = 0;
        else if (idx == 15)
            new_info.D = 0;
    }
    return new_info;
}

int solve(int N, int sx, int sy)
{
    int nx, ny, t;

    //左上のx座標・左上のy座標・何日目か・マス1の雨が降っていない期間
    queue<Info> que;
    Info init_state = {sx, sy, 0, 1, 1, 1, 1};

    bool last_day = false;
    que.push(init_state);
    while (!que.empty())
    {
        Info info = que.front();
        que.pop();

        if (cache[info.t][info.x][info.y][info.A][info.B][info.C][info.D]++)
            continue;
        for (int i = 0; i < 9; i++)
        {
            nx = info.x + dx[i];
            ny = info.y + dy[i];
            t = info.t;
            if (t == N - 1)
            {
                last_day = true;
                break;
            }
            Info new_info = update_info(info, nx, ny);
            if (check_dry(new_info) && check_pos_and_specialday(nx, ny, t + 1))
                que.push(new_info);
        }
    }

    if (last_day)
        return 1;
    else
        return 0;
}

int main()
{
    int N;
    while (cin >> N)
    {
        if (N == 0)
            break;

        for (int i = 0; i < N; i++)
            for (int j = 0; j < AREA_NUM; j++)
                cin >> need_sun[i][j];

        memset(cache, 0, sizeof(cache));
        int ans = solve(N, 1, 1);
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 34656
final_rank: 13

code_snippet: #include <iostream>
#include <algorithm>
#include <queue>
#include <tuple>
#include <cstring>
using namespace std;

const int MAX_N = 370;
const int AREA_NUM = 16;
const int dx[] = {0, 1, 0, -1, 0, 2, 0, -2, 0};
const int dy[] = {0, 0, -1, 0, 1, 0, -2, 0, 2};
const int ax[] = {0, 1, 0, 1};
const int ay[] = {0, 0, 1, 1};
int cache[MAX_N][3][3][7][7][7][7];

int need_sun[MAX_N][AREA_NUM];

struct Info
{
    int x;
    int y;
    int t;
    int A;
    int B;
    int C;
    int D;
};

bool check_border(int x, int y)
{
    return ((0 <= x) && (x < 4) && (0 <= y) && (y < 4));
}

bool check_pos_and_specialday(int left_x, int top_y, int t)
{
    int right_x = left_x + 1;
    int bottom_y = top_y + 1;
    if (check_border(left_x, top_y) &&
        check_border(right_x, bottom_y))
        return (need_sun[t][left_x + top_y * 4] == 0) &&
               (need_sun[t][left_x + bottom_y * 4] == 0) &&
               (need_sun[t][right_x + top_y * 4] == 0) &&
               (need_sun[t][right_x + bottom_y * 4] == 0);
    else
        return false;
}

bool check_dry(Info info)
{
    return info.A < 7 && info.B < 7 && info.C < 7 && info.D < 7;
}

Info update_info(Info info, int nx, int ny)
{
    Info new_info = {nx, ny, info.t + 1,
                     info.A + 1, info.B + 1,
                     info.C + 1, info.D + 1};
    int idx = 0;
    for (int i = 0; i < 4; i++)
    {
        idx = nx + ax[i] + (ny + ay[i]) * 4;
        if (idx == 0)
            new_info.A = 0;
        else if (idx == 3)
            new_info.B = 0;
        else if (idx == 12)
            new_info.C = 0;
        else if (idx == 15)
            new_info.D = 0;
    }
    return new_info;
}

int solve(int N, int sx, int sy)
{
    int nx, ny, t;

    //左上のx座標・左上のy座標・何日目か・マス1の雨が降っていない期間
    queue<Info> que;
    Info init_state = {sx, sy, 0, 1, 1, 1, 1};

    bool last_day = false;
    que.push(init_state);
    while (!que.empty())
    {
        Info info = que.front();
        que.pop();

        if (cache[info.t][info.x][info.y][info.A][info.B][info.C][info.D]++)
            continue;
        for (int i = 0; i < 9; i++)
        {
            nx = info.x + dx[i];
            ny = info.y + dy[i];
            t = info.t;
            if (t == N - 1)
            {
                last_day = true;
                break;
            }
            Info new_info = update_info(info, nx, ny);
            if (check_dry(new_info) && check_pos_and_specialday(nx, ny, t + 1))
                que.push(new_info);
        }
    }

    if (last_day)
        return 1;
    else
        return 0;
}

int main()
{
    int N;
    while (cin >> N)
    {
        if (N == 0)
            break;

        for (int i = 0; i < N; i++)
            for (int j = 0; j < AREA_NUM; j++)
                cin >> need_sun[i][j];

        int ans = 0;
        memset(cache, 0, sizeof(cache));
        // if (check_pos_and_specialday(1, 1, 0))
        ans = solve(N, 1, 1);
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 40
memory_kb: 34628
final_rank: 8

code_snippet: #include <iostream>
#include <algorithm>
#include <queue>
#include <tuple>
#include <cstring>
using namespace std;

const int MAX_N = 370;
const int AREA_NUM = 16;
const int dx[] = {0, 1, 0, -1, 0, 2, 0, -2, 0};
const int dy[] = {0, 0, -1, 0, 1, 0, -2, 0, 2};
const int ax[] = {0, 1, 0, 1};
const int ay[] = {0, 0, 1, 1};
int cache[MAX_N][3][3][7][7][7][7];

int need_sun[MAX_N][AREA_NUM];

struct Info
{
    int x;
    int y;
    int t;
    int A;
    int B;
    int C;
    int D;
};

bool check_border(int x, int y)
{
    return ((0 <= x) && (x < 4) && (0 <= y) && (y < 4));
}

bool check_pos_and_specialday(int left_x, int top_y, int t)
{
    int right_x = left_x + 1;
    int bottom_y = top_y + 1;
    if (check_border(left_x, top_y) &&
        check_border(right_x, bottom_y))
        return (need_sun[t][left_x + top_y * 4] == 0) &&
               (need_sun[t][left_x + bottom_y * 4] == 0) &&
               (need_sun[t][right_x + top_y * 4] == 0) &&
               (need_sun[t][right_x + bottom_y * 4] == 0);
    else
        return false;
}

bool check_dry(Info info)
{
    return info.A < 7 && info.B < 7 && info.C < 7 && info.D < 7;
}

Info update_info(Info info, int nx, int ny)
{
    Info new_info = {nx, ny, info.t + 1,
                     info.A + 1, info.B + 1,
                     info.C + 1, info.D + 1};
    int idx = 0;
    for (int i = 0; i < 4; i++)
    {
        idx = nx + ax[i] + (ny + ay[i]) * 4;
        if (idx == 0)
            new_info.A = 0;
        else if (idx == 3)
            new_info.B = 0;
        else if (idx == 12)
            new_info.C = 0;
        else if (idx == 15)
            new_info.D = 0;
    }
    return new_info;
}

int solve(int N, int sx, int sy)
{
    int nx, ny, t;

    //左上のx座標・左上のy座標・何日目か・マス1の雨が降っていない期間
    queue<Info> que;
    Info init_state = {sx, sy, 0, 1, 1, 1, 1};

    bool last_day = false;
    que.push(init_state);
    while (!que.empty())
    {
        Info info = que.front();
        que.pop();

        if (cache[info.t][info.x][info.y][info.A][info.B][info.C][info.D]++)
            continue;
        for (int i = 0; i < 9; i++)
        {
            nx = info.x + dx[i];
            ny = info.y + dy[i];
            t = info.t;
            if (t == N - 1)
            {
                last_day = true;
                break;
            }
            Info new_info = update_info(info, nx, ny);
            if (check_dry(new_info) && check_pos_and_specialday(nx, ny, t + 1))
                que.push(new_info);
        }
    }

    if (last_day)
        return 1;
    else
        return 0;
}

int main()
{
    int N;
    while (cin >> N)
    {
        if (N == 0)
            break;

        for (int i = 0; i < N; i++)
            for (int j = 0; j < AREA_NUM; j++)
                cin >> need_sun[i][j];

        int ans = 0;
        memset(cache, 0, sizeof(cache));
        if (check_pos_and_specialday(1, 1, 0))
            ans = solve(N, 1, 1);
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 34488
final_rank: 11

code_snippet: #include <iostream>
#include <algorithm>
#include <queue>
#include <tuple>
#include <cstring>
using namespace std;

const int MAX_N = 370;
const int AREA_NUM = 16;
const int dx[] = {0, 1, 0, -1, 0, 2, 0, -2, 0};
const int dy[] = {0, 0, -1, 0, 1, 0, -2, 0, 2};
const int ax[] = {0, 1, 0, 1};
const int ay[] = {0, 0, 1, 1};
int cache[MAX_N][3][3][7][7][7][7];

int need_sun[MAX_N][AREA_NUM];

struct Info
{
    int x;
    int y;
    int t;
    int A;
    int B;
    int C;
    int D;
};

bool check_border(int x, int y)
{
    return ((0 <= x) && (x < 4) && (0 <= y) && (y < 4));
}

bool valid(int left_x, int top_y, int t)
{
    int right_x = left_x + 1;
    int bottom_y = top_y + 1;
    if (check_border(left_x, top_y) &&
        check_border(right_x, bottom_y))
        return (need_sun[t][left_x + top_y * 4] == 0) &&
               (need_sun[t][left_x + bottom_y * 4] == 0) &&
               (need_sun[t][right_x + top_y * 4] == 0) &&
               (need_sun[t][right_x + bottom_y * 4] == 0);
    else
        return false;
}

Info update_info(Info info, int nx, int ny)
{
    Info new_info = {nx, ny, info.t + 1,
                     info.A + 1, info.B + 1,
                     info.C + 1, info.D + 1};
    int idx = 0;
    for (int i = 0; i < 4; i++)
    {
        idx = nx + ax[i] + (ny + ay[i]) * 4;
        if (idx == 0)
            new_info.A = 0;
        else if (idx == 3)
            new_info.B = 0;
        else if (idx == 12)
            new_info.C = 0;
        else if (idx == 15)
            new_info.D = 0;
    }
    return new_info;
}

bool dry_check(Info info)
{
    return info.A < 7 && info.B < 7 && info.C < 7 && info.D < 7;
}

int solve(int N, int sx, int sy)
{
    int nx, ny, t;

    //左上のx座標・左上のy座標・何日目か・マス1の雨が降っていない期間
    queue<Info> que;
    Info init_state = {sx, sy, 0, 1, 1, 1, 1};

    bool last_day = false;
    que.push(init_state);
    while (!que.empty())
    {
        Info info = que.front();
        que.pop();

        if (cache[info.t][info.x][info.y][info.A][info.B][info.C][info.D]++)
            continue;
        for (int i = 0; i < 9; i++)
        {
            nx = info.x + dx[i];
            ny = info.y + dy[i];
            t = info.t;
            if (t == N - 1)
            {
                last_day = true;
                break;
            }
            Info new_info = update_info(info, nx, ny);
            if (dry_check(new_info) && valid(nx, ny, t + 1))
                que.push(new_info);
        }
    }

    if (last_day)
        return 1;
    else
        return 0;
}

int main()
{
    int N;
    while (cin >> N)
    {
        if (N == 0)
            break;

        for (int i = 0; i < N; i++)
            for (int j = 0; j < AREA_NUM; j++)
                cin >> need_sun[i][j];

        int ans = 0;
        memset(cache, 0, sizeof(cache));
        if (valid(1, 1, 0))
            ans = solve(N, 1, 1);
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 34624
final_rank: 12

code_snippet: #include <iostream>
#include <algorithm>
#include <queue>
#include <tuple>
#include <cstring>
using namespace std;

const int MAX_N = 370;
const int AREA_NUM = 16;
const int dx[] = {0, 1, 0, -1, 0, 2, 0, -2, 0};
const int dy[] = {0, 0, -1, 0, 1, 0, -2, 0, 2};
const int ax[] = {0, 1, 0, 1};
const int ay[] = {0, 0, 1, 1};
int cache[MAX_N][3][3][7][7][7][7];

int need_sun[MAX_N][AREA_NUM];

struct Info
{
    int x;
    int y;
    int t;
    int A;
    int B;
    int C;
    int D;
};

bool check_border(int x, int y)
{
    return ((0 <= x) && (x < 4) && (0 <= y) && (y < 4));
}

bool valid(int left_x, int top_y, int t)
{
    int right_x = left_x + 1;
    int bottom_y = top_y + 1;
    if (check_border(left_x, top_y) &&
        check_border(right_x, bottom_y))
        return (need_sun[t][left_x + top_y * 4] == 0) &&
               (need_sun[t][left_x + bottom_y * 4] == 0) &&
               (need_sun[t][right_x + top_y * 4] == 0) &&
               (need_sun[t][right_x + bottom_y * 4] == 0);
    else
        return false;
}

Info update_info(Info info, int nx, int ny)
{
    Info new_info = {nx, ny, info.t + 1,
                     info.A + 1, info.B + 1,
                     info.C + 1, info.D + 1};
    int idx = 0;
    for (int i = 0; i < 4; i++)
    {
        idx = nx + ax[i] + (ny + ay[i]) * 4;
        if (idx == 0)
            new_info.A = 0;
        else if (idx == 3)
            new_info.B = 0;
        else if (idx == 12)
            new_info.C = 0;
        else if (idx == 15)
            new_info.D = 0;
    }
    return new_info;
}

bool dry_check(Info info)
{
    return info.A < 7 && info.B < 7 && info.C < 7 && info.D < 7;
}

int solve(int N, int sx, int sy)
{
    int nx, ny, t;

    //左上のx座標・左上のy座標・何日目か・マス1の雨が降っていない期間
    queue<Info> que;
    Info init_state = {sx, sy, 0, 1, 1, 1, 1};
    int visit[4][4];
    for (int i = 0; i < 16; i++)
        visit[i % 4][i / 4] = 0;

    bool last_day = false;
    que.push(init_state);
    while (!que.empty())
    {
        Info info = que.front();
        que.pop();

        if (cache[info.t][info.x][info.y][info.A][info.B][info.C][info.D]++)
            continue;

        visit[info.x][info.y] = 1;
        visit[info.x + 1][info.y] = 1;
        visit[info.x][info.y + 1] = 1;
        visit[info.x + 1][info.y + 1] = 1;
        for (int i = 0; i < 9; i++)
        {
            nx = info.x + dx[i];
            ny = info.y + dy[i];
            t = info.t;
            if (t == N - 1)
            {
                last_day = true;
                break;
            }
            Info new_info = update_info(info, nx, ny);
            if (dry_check(new_info) && valid(nx, ny, t + 1))
                que.push(new_info);
        }
    }

    int visited_areas = 0;
    for (int i = 0; i < 4; i++)
        for (int j = 0; j < 4; j++)
            visited_areas += visit[i][j];

    if (last_day && (visited_areas == 16))
        return 1;
    else
        return 0;
}

int main()
{
    int N;
    while (cin >> N)
    {
        if (N == 0)
            break;

        for (int i = 0; i < N; i++)
            for (int j = 0; j < AREA_NUM; j++)
                cin >> need_sun[i][j];

        int ans = 0;
        memset(cache, 0, sizeof(cache));
        if (valid(1, 1, 0))
            ans = solve(N, 1, 1);
        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 34416
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define all(A) A.begin(),A.end()
using vll = vector<ll>;
#define rep(i, n) for (long long i = 0; i < (long long)(n); i++)

vector<vll> Q={{1,2,5,6},{2,3,6,7},{3,4,7,8},{5,6,9,10},{6,7,10,11},{7,8,11,12},{9,10,13,14},{10,11,14,15},{11,12,15,16}};
vector<vll> T={{0,1,2,3,6},{0,1,2,4,7},{0,1,2,5,8},{3,4,5,0,6},{3,4,5,1,7},{3,4,5,2,8},{6,7,8,0,3},{6,7,8,1,4},{6,7,8,2,5}};
int main() {
	while(1){
		ll N;
		cin>>N;
		if(N==0)return 0;
		bool CD=false;
		vector<vector<vector<vector<vector<vector<bool>>>>>> DP(N+1,vector<vector<vector<vector<vector<bool>>>>>
		(7,vector<vector<vector<vector<bool>>>>(7,vector<vector<vector<bool>>>(7,vector<vector<bool>>(7,vector<bool>(9,false))))));
		DP[0][1][1][1][1][4]=true;
		vll A(16);
		rep(i,16)cin>>A[i];
		if(A[5]==1||A[6]==1||A[9]==1||A[10]==1)CD=true;

		rep(da,N-1){
			vll A(16);
			rep(i,16)cin>>A[i];
			rep(p,9){
				rep(j,5){
					ll t=T[p][j];
					bool C=true;
					rep(i,4){
						if(A[Q[t][i]-1]==1)C=false;
					}
					if(C){//ここに動かせる.
						if(t==0){
							rep(a,7)rep(b,6)rep(c,6)rep(d,6){
							if(DP[da][a][b][c][d][p]){
								DP[da+1][0][b+1][c+1][d+1][t]=true;
							}
							}
						}
						else if(t==2){
							rep(a,6)rep(b,7)rep(c,6)rep(d,6){
							if(DP[da][a][b][c][d][p]){
								DP[da+1][a+1][0][c+1][d+1][t]=true;
							}
							}
						}
						else if(t==6){
							rep(a,6)rep(b,6)rep(c,7)rep(d,6){
							if(DP[da][a][b][c][d][p]){
								DP[da+1][a+1][b+1][0][d+1][t]=true;
							}
							}
						}
						else if(t==8){
							rep(a,6)rep(b,6)rep(c,6)rep(d,7){
							if(DP[da][a][b][c][d][p]){
								DP[da+1][a+1][b+1][c+1][0][t]=true;
							}
							}
						}
						else{
							rep(a,6)rep(b,6)rep(c,6)rep(d,6){
							if(DP[da][a][b][c][d][p]){
								DP[da+1][a+1][b+1][c+1][d+1][t]=true;
							}
							}
						}





						




					}
				}
			}
		}




		if(CD)cout<<0<<endl;
		else{
			bool C=false;
			rep(a,7)rep(b,7)rep(c,7)rep(d,7)rep(p,9){
				if(DP[N-1][a][b][c][d][p])C=true;
			}
			cout<<C<<endl;

		}
	}
	
}
accuracy: 1
time_ms: 290
memory_kb: 69944
final_rank: 17

code_snippet: #include<iostream>
#include<vector>
using namespace std;
int N;
bool dp[2][9][9][9][9][9][9];
int ok[365];
void clr(int id)
{
	for(int i=0;i<9;i++)for(int j=0;j<9;j++)for(int k=0;k<9;k++)for(int l=0;l<9;l++)for(int m=0;m<9;m++)for(int n=0;n<9;n++)dp[id][i][j][k][l][m][n]=false;
}
int G[9];
bool check[9][9][9][9][9][9][9];
int main()
{
	for(int x=0;x<3;x++)for(int y=0;y<3;y++)
	{
		for(int tx=0;tx<3;tx++)for(int ty=0;ty<3;ty++)
		{
			if(x==tx||y==ty)G[x*3+y]|=1<<tx*3+ty;
		}
	}
	for(int a=0;a<9;a++)for(int b=0;b<9;b++)for(int c=0;c<9;c++)for(int d=0;d<9;d++)for(int e=0;e<9;e++)for(int f=0;f<9;f++)for(int g=0;g<9;g++)
	{
		bool ok=true;
		for(int k:{0,2,6,8})
		{
			if(a-k&&b-k&&c-k&&d-k&&e-k&&f-k&&g-k)ok=false;
		}
		check[a][b][c][d][e][f][g]=ok;
	}
	while(cin>>N,N)
	{
		for(int i=0;i<N;i++)
		{
			int c[4][4];
			for(int j=0;j<4;j++)for(int k=0;k<4;k++)cin>>c[j][k];
			ok[i]=0;
			for(int x=0;x<3;x++)for(int y=0;y<3;y++)
			{
				if(!(c[x][y]||c[x][y+1]||c[x+1][y]||c[x+1][y+1]))ok[i]|=1<<x*3+y;
			}
		}
		if(!(ok[0]>>4&1))
		{
			cout<<0<<endl;
			continue;
		}
		int now=0;
		clr(now);
		dp[now][0][0][0][0][0][4]=true;
		for(int i=1;i<N;i++)
		{
			int nxt=1-now;
			clr(nxt);
			for(int a=0;a<9;a++)for(int b=0;b<9;b++)for(int c=0;c<9;c++)for(int d=0;d<9;d++)for(int e=0;e<9;e++)for(int f=0;f<9;f++)if(dp[now][a][b][c][d][e][f])
			{
				int to=G[f]&ok[i];
				for(int g=0;g<9;g++)if(to>>g&1)
				{
					if(i>=6&&!check[a][b][c][d][e][f][g])continue;
					dp[nxt][b][c][d][e][f][g]=true;
				}
			}
			now=nxt;
		}
		bool ok=false;
		for(int a=0;a<9;a++)for(int b=0;b<9;b++)for(int c=0;c<9;c++)for(int d=0;d<9;d++)for(int e=0;e<9;e++)for(int f=0;f<9;f++)if(dp[now][a][b][c][d][e][f])ok=true;
		cout<<(ok?1:0)<<endl;
	}
}
accuracy: 1
time_ms: 760
memory_kb: 9152
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)

int N;
vector<int> cnt;
vector<vector<int>> sched;
set<pair<int, vector<int>>> st;

int di[4] = {0, 1, 0, -1};
int dj[4] = {1, 0, -1, 0};

bool dfs(int day, int p) {
    if (day == N) return true;
    if (st.count({day, cnt})) {
        return false;
    }
    rep(i,0,16) if (cnt[i] >= 7) return false;
    rep(i,0,16) if (sched[day][i] && cnt[i] == 0) return false;
    auto tmp = cnt;
    int i = p/4, j=p%4;
    rep(k,1,3) {
        rep(d,0,4) {
            int ni = i + k*di[d], nj = j + k*dj[d];
            if (0 <= ni && ni < 3 && 0 <= nj && nj < 3) {
                rep(x,0,16) cnt[x]++;
                cnt[4*ni+nj] = cnt[4*ni+nj+1] = cnt[4*(ni+1)+nj] = cnt[4*(ni+1)+nj+1] = 0;
                if (dfs(day+1, 4*ni+nj)) return true;
                cnt = tmp;
            }
        }
    }
    rep(x,0,16) cnt[x]++;
    cnt[4*i+j] = cnt[4*i+j+1] = cnt[4*(i+1)+j] = cnt[4*(i+1)+j+1] = 0;
    if (dfs(day+1, 4*i+j)) return true;
    cnt = tmp;
    st.insert({day, cnt});
    return false;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    while (1) {
        cin >> N;
        if (N==0) break;
        st.clear();
        sched.resize(N, vector<int>(16));
        rep(i,0,N) rep(j,0,16) cin >> sched[i][j];
        cnt.assign(16,1);
        cnt[5] = cnt[6] = cnt[9] = cnt[10] = 0;
        cout << dfs(0, 5) << endl;
    }
}
accuracy: 1
time_ms: 150
memory_kb: 19552
final_rank: 15

code_snippet: #pragma region Macros
#include <bits/stdc++.h>
using namespace std;
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

struct Setup {
    Setup() {
        cin.tie(0);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
    }
} __Setup;

using ll = long long;
#define OVERLOAD3(_1, _2, _3, name, ...) name
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define REP1(i, n) for(int i = 0; i < (n); i++)
#define REP2(i, a, b) for(int i = (a); i < int(b); i++)
#define REP(...) OVERLOAD3(__VA_ARGS__, REP2, REP1)(__VA_ARGS__)
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;
constexpr int MOD = 1000000007;
constexpr int MOD2 = 998244353;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

void Case(int i) { cout << "Case #" << i << ": "; }
int popcount(int x) { return __builtin_popcount(x); }
ll popcount(ll x) { return __builtin_popcountll(x); }
#pragma endregion Macros

using arr = array<int, 16>;

bool solve() {
    int N;
    cin >> N;
    if(N == 0) return false;
    vector<arr> schedules(N);
    REP(i, N) REP(j, 16) cin >> schedules[i][j];

    vector<map<arr, int>> memo(16);
    arr now;
    bool ans = false;
    REP(i, 16) now[i] = 1;
    now[5] = now[6] = now[9] = now[10] = 0;
    auto dfs = [&](auto&& self, int cx, int cy, int d) -> void {
        if(ans) return;
        if(d >= N) {
            // debug(cx, cy, d);
            // REP(i, 16) cerr << now[i] << ' ';
            // cerr << endl;
            ans = true;
            return;
        }
        REP(x, 4) REP(y, 4) {
            if(now[x*4 + y] >= 7) return;
            if(now[x*4 + y] == 0 and schedules[d][x*4 + y]) return;
        }
        if(memo[cx*4 + cy].count(now) and memo[cx*4 + cy][now] >= d) return;
        // debug(cx, cy, d);
        // REP(i, 16) cerr << now[i] << ' ';
        // cerr << endl;
        memo[cx*4 + cy][now] = d;
        REP(dir, 4) REP(w, 3) {
            int nx = cx + dx[dir] * w;
            int ny = cy + dy[dir] * w;
            if(nx < 0 or nx >= 3 or ny < 0 or ny >= 3) continue;
            auto tmp = now;
            REP(x, 4) REP(y, 4) {
                if(nx <= x and x <= nx+1 and ny <= y and y <= ny+1) now[x*4 + y] = 0;
                else now[x*4 + y] += 1;
            }
            self(self, nx, ny, d+1);
            now = tmp;
        }
    };
    dfs(dfs, 1, 1, 0);
    cout << ans << '\n';
    return true;
}

int main() {
    while(solve());
}
accuracy: 1
time_ms: 20
memory_kb: 3928
final_rank: 1