USACO All Latin Squares解題レポート

3803 ワード

この問題はここまでにしましょう.
running... real 0m18.792s user 0m18.564s sys 0m0.149s result: 12198297600
/*
 ID: thestor1
 LANG: C++
 TASK: latin
 */
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <climits>
#include <cassert>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <cassert>

using namespace std;

void DFS(int r, int c, const int N, unsigned long long int &cnt, vector<vector<bool> > &appearedrow, vector<vector<bool> > &appearedcol, vector<int> &sumrow);

void printSquare(vector<vector<int> > &square)
{
	cout << "[debug]square:" << endl;
	for (int i = 0; i < square.size(); ++i)
	{
		for (int j = 0; j < square[i].size(); ++j)
		{
			cout << square[i][j];
		}
		cout << endl;
	}
}

void DFS(int r, int c, const int N, unsigned long long int &cnt, vector<vector<bool> > &appearedrow, vector<vector<bool> > &appearedcol, vector<int> &sumrow)
{
	// cout << "[debug][DFS]r: " << r << ", c: " << c << endl;
	// printSquare(square);

	if (r == N - 1)
	{
		// cout << "[debug]" << cnt << endl;
		cnt++;
		return;
	}

	int num;
	if (c == N - 1)
	{
		num = N * (N - 1) / 2 - sumrow[r];
		if (!appearedcol[num][c])
		{
			appearedcol[num][c] = true;
			DFS(r + 1, 1, N, cnt, appearedrow, appearedcol, sumrow);
			appearedcol[num][c] = false;
			// fill(r, c, num, N, cnt, appearedrow, appearedcol, sumrow);
		}
	}
	else
	{
		for (int num = 0; num < N; ++num)
		{
			if (!appearedrow[num][r] && !appearedcol[num][c])
			{
				appearedrow[num][r] = true;
				appearedcol[num][c] = true;
				sumrow[r] += num;
				DFS(r, c + 1, N, cnt, appearedrow, appearedcol, sumrow);
				sumrow[r] -= num;
				appearedrow[num][r] = false;
				appearedcol[num][c] = false;
			}
		}
	}
}

int main()
{
	ifstream fin("latin.in");
	int N;
	fin >> N;
	fin.close();


	if (N == 2)
	{
		ofstream fout("latin.out");
		fout << 1 << endl;
		fout.close();
		return 0;
	}

	// if (N == 7)
	// {
	// 	ofstream fout("latin.out");
	// 	fout << 12198297600 << endl;
	// 	fout.close();
	// 	return 0;
	// }
	
	// vector<vector<int> > square(N, vector<int>(N, 0));
	vector<vector<bool> > appearedrow(N, vector<bool>(N, false));
	vector<vector<bool> > appearedcol(N, vector<bool>(N, false));
	vector<int> sumrow(N, 0);
	// vector<int> sumcol(N, 0);
	
	for (int i = 0; i < N; ++i)
	{
		// square[0][i] = i;
		appearedrow[i][0] = true;
		appearedcol[i][i] = true;
		sumrow[0] += i;
		// sumcol[i] += i;
	}

	for (int i = 0; i < N; ++i)
	{
		// square[i][0] = i;
		appearedrow[i][i] = true;
		appearedcol[i][0] = true;
		sumrow[i] += i;
		// sumcol[0] += i;
	}

	unsigned long long int cnt = 0;

	// square[1][1] = 0;
	appearedrow[0][1] = true;
	appearedcol[0][1] = true;
	sumrow[1] += 0;
	unsigned long long int cnt1 = 0;
	DFS(1, 2, N, cnt1, appearedrow, appearedcol, sumrow);
	cnt += cnt1;

	// square[1][1] = 2;
	appearedrow[0][1] = false;
	appearedcol[0][1] = false;
	appearedrow[2][1] = true;
	appearedcol[2][1] = true;
	sumrow[1] -= 0;
	sumrow[1] += 2;
	
	cnt1 = 0;
	DFS(1, 2, N, cnt1, appearedrow, appearedcol, sumrow);
	cnt += cnt1 * (N - 2);

	for (int i = N - 1; i > 1; --i)
	{
		cnt *= i;
	}

	ofstream fout("latin.out");
	fout << cnt << endl;
	fout.close();
	return 0;  
}