Problem:
Board Arrangements for Concentration Games
You have to organize a wedding party. The program of the
party will include a concentration game played by the
bride and groom. The arrangement of the concentration game
should be easy since this game will be played to make the
party fun.
We have a 4x4 board and 8 pairs of cards (denoted by `A' to `H')
for the concentration game:
+---+---+---+---+ 
   |   |   |   |   |   A A B B
   +---+---+---+---+   C C D D
   |   |   |   |   |   E E F F
   +---+---+---+---+   G G H H
   |   |   |   |   |
   +---+---+---+---+ 
   |   |   |   |   |
   +---+---+---+---+
To start the game, it is necessary to arrange all 16 cards
face down on the board. For example:
+---+---+---+---+ 
   | A | B | A | B |
   +---+---+---+---+
   | C | D | C | D |
   +---+---+---+---+
   | E | F | G | H |
   +---+---+---+---+ 
   | G | H | E | F |
   +---+---+---+---+
The purpose of the concentration game is to expose as many
cards as possible by repeatedly performing the following
procedure: (1) expose two cards, (2) keep them open if they
match or replace them face down if they do not.
Since the arrangements should be simple, every pair of cards
on the board must obey the following condition: the
relative position of one card to the other card of the pair must be
one of 4 given relative positions.
The 4 relative positions are different from one another and
they are selected from the following 24 candidates:
(1, 0), (2, 0), (3, 0),
   (-3, 1), (-2, 1), (-1, 1), (0, 1), (1, 1), (2, 1), (3, 1),
   (-3, 2), (-2, 2), (-1, 2), (0, 2), (1, 2), (2, 2), (3, 2),
   (-3, 3), (-2, 3), (-1, 3), (0, 3), (1, 3), (2, 3), (3, 3).
Your job in this problem is to write a program that
reports the total number of board arrangements which satisfy
the given constraint.  For example, if relative positions
(-2, 1), (-1, 1), (1, 1), (1, 2) are given, the total number
of board arrangements is two, where the following two
arrangements satisfy the given constraint:
X0  X1  X2  X3             X0  X1  X2  X3
    +---+---+---+---+          +---+---+---+---+ 
 Y0 | A | B | C | D |       Y0 | A | B | C | D | 
    +---+---+---+---+          +---+---+---+---+ 
 Y1 | B | A | D | C |       Y1 | B | D | E | C | 
    +---+---+---+---+          +---+---+---+---+ 
 Y2 | E | F | G | H |       Y2 | F | A | G | H | 
    +---+---+---+---+          +---+---+---+---+ 
 Y3 | F | E | H | G |       Y3 | G | F | H | E | 
    +---+---+---+---+          +---+---+---+---+ 
 the relative positions:    the relative positions:
    A:(1, 1),  B:(-1, 1)       A:(1, 2),  B:(-1, 1)
    C:(1, 1),  D:(-1, 1)       C:(1, 1),  D:(-2, 1)
    E:(1, 1),  F:(-1, 1)       E:(1, 2),  F:( 1, 1)
    G:(1, 1),  H:(-1, 1)       G:(-2, 1), H:(-1, 1)
Arrangements of the same pattern should be counted only once.  Two
board arrangements are said to have the same pattern if they are
obtained from each other by repeatedly making any two pairs exchange
their positions.  For example, the following two arrangements have th
...(truncated)

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef vector<vi> vvi;
#define FOR(i,l,r) for(int i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(A) A.begin(),A.end()
int main(){
    while(1){
        vector<pair<int,int>>A(4);
        REP(i,4)cin>>A[i].first>>A[i].second;
        if(A[0].first>4)break;
        vector<int>C;
        REP(i,4)REP(j,4)REP(k,4)if(0<=min(i+A[k].first,j+A[k].second)&&4>max(i+A[k].first,j+A[k].second)){
            C.emplace_back((1<<(4*i+j))+(1<<(4*(i+A[k].first)+j+A[k].second)));
        }
        sort(ALL(C));
        vvi dp(C.size()+1,vi(65536));
        dp[0][0]=1;
        REP(i,C.size())REP(j,65536){
            dp[i+1][j]+=dp[i][j];
            if(!(j&C[i]))dp[i+1][j+C[i]]+=dp[i][j];
        }
        cout<<dp[C.size()][65535]<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 23112
final_rank: 9

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define inRange(x,a,b) (a <= x && x < b)
typedef long long ll;

int main(){
    int x[4], y[4];
    while(cin >> x[0], x[0] < 4){
        cin >> y[0];
        for(int i = 1; i < 4; i++)  cin >> x[i] >> y[i];
        vector<int> v;
        for(int i = 0; i < 4; i++){
            for(int j = 0; j < 4; j++){
                int origin = i*4+j;
                for(int k = 0; k < 4; k++){
                    int ni = i+x[k], nj = j+y[k];
                    if(!inRange(ni,0,4)||!inRange(nj,0,4))  continue;
                    int next = ni*4+nj;
                    v.push_back((1<<origin) + (1<<next));
                }
            }
        }
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());
        vector<ll> dp(1<<16, 0);
        dp[0] = 1;
        for(int s = 0; s < 1<<16; s++){
            for(int j : v){
                if((s&j) == 0)  dp[s^j] += dp[s];
            }
        }
        cout << dp.back()/40320 << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3648
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
typedef pair<int,int> P;
bool check(int x,int y){return x>=0&&x<4&&y>=0&&y<4;}
 
int main() {
  int n=8,m=4;
  P d[n];
  while(cin >> d[0].F >> d[0].S) {
    for(int i=1; i<m; i++) cin >> d[i].F >> d[i].S;
    for(int i=0; i<n; i++) {
      if(d[i].F<0) {
        d[i].F*=-1;
        d[i].S*=-1;
      }
      if(d[i].F==0&&d[i].S<0) d[i].S*=-1;
    }
    int ans=0;
    for(int t=0; t<(1<<(n*2)); t++) {
      P a[n];
      for(int i=0; i<n; i++) {
        int x=t/(1<<(i*2));
        x%=4;
        a[i]=d[x];
      }
      int c[m][m];
      memset(c,-1,sizeof(c));
      int k=0;
      for(int i=0; i<m; i++) {
        for(int j=0; j<m; j++) {
          if(c[i][j]==-1) {
            int x=i+a[k].F,y=j+a[k].S;
            if(!check(x,y)||c[x][y]!=-1) goto next;
            c[i][j]=k;
            c[x][y]=k;
            k++;
          }
        }
      }
      ans++;
    next:;
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3088
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
typedef pair<int,int> P;
bool check(int x,int y){return x>=0&&x<4&&y>=0&&y<4;}

int main() {
  int n=8,m=4;
  P d[n];
  while(cin >> d[0].F >> d[0].S) {
    for(int i=1; i<m; i++) cin >> d[i].F >> d[i].S;
    for(int i=0; i<n; i++) {
      if(d[i].F<0) {
        d[i].F*=-1;
        d[i].S*=-1;
      }
      if(d[i].F==0&&d[i].S<0) d[i].S*=-1;
    }
    int ans=0;
    for(int t=0; t<(1<<(n*2)); t++) {
      P a[n];
      for(int i=0; i<n; i++) {
        int x=t/(1<<(i*2));
        x%=4;
        a[i]=d[x];
      }
      int c[m][m];
      memset(c,-1,sizeof(c));
      int k=0;
      for(int i=0; i<m; i++) {
        for(int j=0; j<m; j++) {
          if(c[i][j]==-1) {
            int x=i+a[k].F,y=j+a[k].S;
            if(!check(x,y)||c[x][y]!=-1) goto next;
            c[i][j]=k;
            c[x][y]=k;
            k++;
          }
        }
      }
      ans++;
    next:;
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 2992
final_rank: 4

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
int dp[1<<16];
int x[5];
int y[5];
int main(){
	int a;
	while(scanf("%d",&a),a<=4){
		x[0]=a;
		scanf("%d%d%d%d%d%d%d",y,x+1,y+1,x+2,y+2,x+3,y+3);
		for(int i=0;i<(1<<16);i++)dp[i]=0;
		dp[0]=1;
		for(int i=0;i<(1<<16);i++){
	//		if(dp[i])printf("%d: %d\n",i,dp[i]);
			for(int j=0;j<16;j++){
				if(!(i&(1<<j))){
					int row=j/4;int col=j%4;
					for(int k=0;k<4;k++){
						int tr=row+y[k];
						int tc=col+x[k];
						if(tr<0||tc<0||tr>3||tc>3||((i+(1<<j))&(1<<(tr*4+tc))))continue;
						dp[i+(1<<j)+(1<<(tr*4+tc))]+=dp[i];
					}
					break;
				}
			}
		}
		printf("%d\n",dp[(1<<16)-1]);
	}
}
accuracy: 1
time_ms: 10
memory_kb: 1284
final_rank: 3

code_snippet: #include<iostream>
#include<set>
#include<cassert>
#include<cmath>
#include<vector>
#include<algorithm>
 
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<29)
 
using namespace std;
 
typedef pair<int,int> ii;
set<string> used;
int cnt = 0;
ii raint[4];
 
void dfs(int cur,int st,string perm)
{
  if(cur >= 8)
    {
      if(used.find(perm) != used.end())return;
      used.insert(perm);
      rep(i,16)if(perm[i] == 'x')return;
    cnt++;
      return;
    }
 
  REP(i,st,16)
    {
      int x = i%4;
      int y = i/4;
      rep(j,4)
    {
      int nx = x + raint[j].first;
      int ny = y + raint[j].second;
      if(!(0 <= nx && nx < 4 && 0 <= ny && ny < 4))continue;
      if(perm[nx+ny*4] != 'x')continue;
      string nperm = perm;
      nperm[x+y*4] = nperm[nx+ny*4] = (char)('0'+cur);
      dfs(cur+1,i+1,nperm);
    }
    }
 
}
 
int main()
{
  while(cin >> raint[0].first,raint[0].first <= 4)
    {
      used.clear();
      cin >> raint[0].second;
      REP(i,1,4)cin >> raint[i].first >> raint[i].second;
      cnt = 0;
      string perm = string(16,'x');
 
      dfs(0,0,perm);
 
      cout << cnt << endl;
    }
}
accuracy: 1
time_ms: 250
memory_kb: 6992
final_rank: 10

code_snippet: #include<iostream>
#include<set>
#include<cassert>
#include<cmath>
#include<vector>
#include<algorithm>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<29)

using namespace std;

typedef pair<int,int> ii;
set<string> used;
int cnt = 0;
ii raint[4];

void dfs(int cur,int st,string perm)
{
  if(cur >= 8)
    {
      if(used.find(perm) != used.end())return;
      used.insert(perm);
      rep(i,16)if(perm[i] == 'x')return;
	cnt++;
      return;
    }

  REP(i,st,16)
    {
      int x = i%4;
      int y = i/4;
      rep(j,4)
	{
	  int nx = x + raint[j].first;
	  int ny = y + raint[j].second;
	  if(!(0 <= nx && nx < 4 && 0 <= ny && ny < 4))continue;
	  if(perm[nx+ny*4] != 'x')continue;
	  string nperm = perm;
	  nperm[x+y*4] = nperm[nx+ny*4] = (char)('0'+cur);
	  dfs(cur+1,i+1,nperm);
	}
    }

}

int main()
{
  while(cin >> raint[0].first,raint[0].first <= 4)
    {
      used.clear();
      cin >> raint[0].second;
      REP(i,1,4)cin >> raint[i].first >> raint[i].second;
      cnt = 0;
      string perm = string(16,'x');

      dfs(0,0,perm);

      cout << cnt << endl;
    }
}
accuracy: 1
time_ms: 260
memory_kb: 6992
final_rank: 11

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

const int dx[24] = {-3,-3,-3,-2,-2,-2,-1,-1,-1,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3};
const int dy[24] = {1,2,3,1,2,3,1,2,3,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3};
const int H = 4;
const int W = 4;
const int N = H*W;
int dp[2][1<<N];

int main() {
  int dx[4], dy[4];
  while(cin >> dx[0] && dx[0] <= 4) {
    cin >> dy[0];
    for(int i = 1; i < 4; ++i) cin >> dx[i] >> dy[i];

    fill(dp[0], dp[2], 0);
    dp[0][0] = 1;
    for(int t = 0; t < N; ++t) {
      int i = t / W; 
      int j = t % W;
      int p = t % 2;
      int q = 1 - p;
      for(int k = 0; k < (1<<N); ++k) dp[q][k] = 0;
      for(int k = 0; k < (1<<N); ++k) {
        if(k & (1<<t)) {
          dp[q][k] += dp[p][k];
        } else {
          for(int m = 0; m < 4; ++m) {
            int ni = i + dy[m];
            int nj = j + dx[m];
            int nt = ni * W + nj;
            if(ni < 0 || ni >= H) continue;
            if(nj < 0 || nj >= W) continue;
            if(k & (1<<nt)) continue;
            dp[q][k|(1<<t)|(1<<nt)] += dp[p][k];
          }
        }
      }
    }
    cout << dp[N%2][(1<<N)-1] << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 1672
final_rank: 6

code_snippet: #include <iostream>
#include <algorithm>
#include <cstring>

#define LP(i,n) for(int i = 0; i < n; i++)

using namespace std;

int s;
int x[4][2];

void comb(int y[8], int n){
	if(n == 8){
		int p[4][4];
		memset(p,0,sizeof p);
		int idx = 0;
		for(int j = 0 ; j< 4 ;j++){
			for(int i = 0; i < 4; i++){
				if(p[i][j]==0){
					if(0<=i+x[y[idx]][0]&&i+x[y[idx]][0]<4&&0<=j+x[y[idx]][1]&&j+x[y[idx]][1]<4&&p[i+x[y[idx]][0]][j+x[y[idx]][1]] == 0){
						p[i+x[y[idx]][0]][j+x[y[idx]][1]] = ++idx;
					}else return;
				}
			}
		}
		s++;
		return;
	}
	for(int i = 0; i < 4; i++){
		y[n] = i;
		comb(y,n+1);
	}
}

int main(){
	cin >> **x;
	while(**x < 5){
		s = 0;
		for(int i = 1; i < 8; i++){
			cin >> *(*x+i);
		}
		int y[8];
		comb(y,0);
		cout << s << endl;
		cin >> **x;
	}
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include<iostream>
#include<set>
using namespace std;

struct board{
  char M[4][4];
  board(){
    for(int i = 0; i < 4; ++i)for(int j = 0; j < 4; ++j)M[i][j]='*';
  }
  bool isinside(const pair<int,int> &p)const{
    return 0<=p.first&&p.first<4&&0<=p.second&&p.second<4;
  }
  bool fillable(const pair<int,int> &p)const{
    return M[p.first][p.second]=='*';
  }
  bool filled()const{
    for(int i = 0; i < 4; ++i)
      for(int j = 0; j < 4; ++j)
	if(M[i][j]=='*')return false;
    return true;
  }
  bool operator<(const board &b)const{
    for(int i=0;i<4;++i){
      for(int j=0;j<4;++j){
	if(M[i][j]!=b.M[i][j])return M[i][j]<b.M[i][j];
      }
    }
    return false;
  }
  void print()const{
    for(int i = 0; i < 4; ++i){
      for(int j = 0; j < 4; ++j){
	cout << M[i][j] << ' ';
      }
      cout << endl;
    }
    cout << endl;
  }
};

void dfsFill(char c, board &b, pair<int,int> relpos[4], set<board> &vis, set<board> &S){
  if(vis.find(b)==vis.end()){
    vis.insert(b);
  }else return ;
  if(b.filled()){
    S.insert(b);
  }
  for(int i = 0; i < 4; ++i){
    for(int j = 0; j < 4; ++j){
      for(int k = 0; k < 4; ++k){
	pair<int,int> np(i,j);
	pair<int,int> next(i+relpos[k].first,j+relpos[k].second);
	if(b.isinside(next)&&b.fillable(np)&&b.fillable(next)){
	  char t1,t2;
	  t1=b.M[np.first][np.second];
	  b.M[np.first][np.second]=c+k;
	  t2=b.M[next.first][next.second];
	  b.M[next.first][next.second]=c+k;

	  dfsFill(c,b,relpos,vis,S);

	  b.M[next.first][next.second]=t2;
	  b.M[np.first][np.second]=t1;
	}
      }
    }
  }
}

int solve(pair<int,int> relpos[4]){
  board init;
  set<board> S,vis;
  dfsFill('A', init, relpos, vis, S);
  return S.size();
}

int main(){
  while(true){
    pair<int,int> relpos[4];
    for(int i = 0; i < 4; ++i){
      int x,y;
      cin >> x;
      if(x>4)return 0;
      cin >> y;
      relpos[i] = make_pair(y,x);
    }
    cout << solve(relpos) << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 2372
final_rank: 8

code_snippet: #include<iostream>
#include<map>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;
pair<int,int> rp[4];
char bd[4][4];
int dfs(char c){
	if(c=='I')return 1;
	int r=0;
	rep(y,4)rep(x,4)if(bd[y][x]=='.'){
		bd[y][x]=c;
		rep(k,4){
			int ny=y+rp[k].first,nx=x+rp[k].second;
			if(0<=ny&&ny<4&&0<=nx&&nx<4&&bd[ny][nx]=='.'){
				bd[ny][nx]=c;
				r+=dfs(c+1);
				bd[ny][nx]='.';
			}
		}
		bd[y][x]='.';
		if(r>0)return r;
	}
	return 0;
}
int main(){
	int a,b;
	while(cin>>a,a<5){
		cin>>b; rp[0]=make_pair(b,a);
		rep(i,3)cin>>a>>b,rp[i+1]=make_pair(b,a);
		rep(i,4)rep(j,4)bd[i][j]='.';
		cout<<dfs('A')<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1