USACO 6.5 All Latin Squares
All Latin Squares
A square arrangement of numbers
1 2 3 4 5
2 1 4 5 3
3 4 5 1 2
4 5 2 3 1
5 3 1 2 4
is a 5 x 5 Latin Square because each whole number from 1 to 5 appears once and only once in each row and column.
Write a program that will compute the number of NxN Latin Squares whose first row is:
1 2 3 4 5.......N
Your program should work for any N from 2 to 7.
PROGRAM NAME: latin
INPUT FORMAT
One line containing the integer N.
SAMPLE INPUT (file latin.in)
5
OUTPUT FORMAT
A single integer telling the number of latin squares whose first row is 1 2 3 . . . N.
SAMPLE OUTPUT (file latin.out)
1344 ————————————————————题解
第一行已经固定了,如果我们固定第一列为1 2 3 4 5……n 那么我们计算出的方案数乘以(n-1)!即可
然后这个优化加上位运算也只能过6。7就很尴尬了。
还有一个神一般的优化
例如
1 2 3 4 5
2 1 4 3 5
这其中有两个置换圈 1,2 和 3,4,5
如果再来一种搜索搜到了
1 2 3 4 5
2 3 1 5 4
这其中有两个置换圈 1 2 3 和 4 5
注意到了吗这个置换圈要先从大到小排序
这样的话其实这两种情况是等价的
为什么等价?
长度为2的两个圈 1 2 和 4 5可以分别一一对应
长度为3的两个圈3 4 5 和 1 2 3可以分别一一对应
也就是像我们手里得到了一张转换表,把第一种情况里的后四排的
1写成4
2写成5
3写成1
4写成2
5写成3
最后得到了一个新的拉丁方格
所以我们用一个哈希表记录置换圈的长度和所有置换圈长度的乘积,算过一遍的方案直接得出,节省很多时间……
orz反正我是想不到的
/*
LANG: C++
PROG: latin
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define siji(i,x,y) for(int i=(x); i<=(y) ; ++i)
#define ivorysi
#define o(x) ((x)*(x))
using namespace std;
typedef long long ll;
int n;
int col[],row[],num[][];
bool v[];
ll ans,h[][];//置换圈的长度乘积,个数
void init() {
scanf("%d",&n);
siji(i,,n) {
num[][i]=i;
num[i][]=i;
col[i]=(<<i);
row[i]=(<<i);
}
memset(h,-,sizeof(h));
} ll dfs(int x,int y) {
if(x>=n){
return ;
}
ll res=;
if(x==&&y==) {
memset(v,,sizeof(v));
int cnt=,len=;
siji(i,,n) {
if(v[i]) continue;
v[i]=;
int rec=;
for(int l=num[][i];l!=i;l=num[][l]) {
v[l]=;
++rec;
}
len*=rec;
++cnt;
}
if(h[len][cnt]!=-) return h[len][cnt];
siji(i,,n) {
if(((col[y]&(<<i))==) && ((row[x]&(<<i))==)) {
col[y]|=(<<i);
row[x]|=(<<i);
num[x][y]=i;
if(y==n) res+=dfs(x+,);
else res+=dfs(x,y+);
col[y]^=(<<i);
row[x]^=(<<i);
num[x][y]=;
}
}
return h[len][cnt]=res;
}
siji(i,,n) {
if(((col[y]&(<<i))==) && ((row[x]&(<<i))==)) {
col[y]|=(<<i);
row[x]|=(<<i);
num[x][y]=i;
if(y==n) res+=dfs(x+,);
else res+=dfs(x,y+);
col[y]^=(<<i);
row[x]^=(<<i);
num[x][y]=;
}
}
return res;
}
void solve() {
init();
//if(n==7) {cout<<"12198297600"<<endl;return;}
ans=dfs(,);
siji(i,,n-) ans*=i;
printf("%lld\n",ans);
}
int main(int argc, char const *argv[])
{
#ifdef ivorysi
freopen("latin.in","r",stdin);
freopen("latin.out","w",stdout);
#else
freopen("f1.in","r",stdin);
//freopen("f1.out","w",stdout);
#endif
solve();
return ;
}
USACO 6.5 All Latin Squares的更多相关文章
- 【USACO 3.2】Magic Squares
题意 4*2个格子分别为 1234 8765 的魔板有3种操作,A:上下两排互换,B:最后一列放到第一列前面,C:中间四个顺时针旋转1格. 现在给出目标状态,找出最少步数可从原始状态到达目标状态,且输 ...
- 【USACO 1.2】Palindromic Squares
进制转换,然后判断是否是回文 /******************************************* TASK: palsquare LANG: C++ Created Time: ...
- USACO Section 1.2 Palindromic Squares 解题报告
题目 题目描述 输入一个基数B,现在要从1到300之间找出一些符合要求的数字N.如果N的平方转换成B进制数之后是一个回文串,那么N就符合要求.我们将N转换成B进制数输出,然后再将N的平方转换成B进制数 ...
- USACO 完结的一些感想
其实日期没有那么近啦……只是我偶尔还点进去造成的,导致我没有每一章刷完的纪念日了 但是全刷完是今天啦 讲真,题很锻炼思维能力,USACO保持着一贯猎奇的题目描述,以及尽量不用高级算法就完成的题解……例 ...
- USACO 6.5 章节 世界上本没有龙 屠龙的人多了也便有了
All Latin Squares 题目大意 n x n矩阵(n=2->7) 第一行1 2 3 4 5 ..N 每行每列,1-N各出现一次,求总方案数 题解 n最大为7 显然打表 写了个先数值后 ...
- Project Euler 96:Su Doku 数独
Su Doku Su Doku (Japanese meaning number place) is the name given to a popular puzzle concept. Its o ...
- [转]100个经典C语言程序(益智类问题)
目录: 1.绘制余弦曲线 2.绘制余弦曲线和直线 3.绘制圆 4.歌星大奖赛 5.求最大数 6.高次方数的尾数 8.借书方案知多少 9.杨辉三角形 10.数制转换 11.打鱼还是晒网 12.抓交通肇事 ...
- 【算法】C语言趣味程序设计编程百例精解
C语言趣味程序设计编程百例精解 C/C++语言经典.实用.趣味程序设计编程百例精解(1) https://wenku.baidu.com/view/b9f683c08bd63186bcebbc3c. ...
- List of NP-complete problems
This is a list of some of the more commonly known problems that are NP-complete when expressed as de ...
随机推荐
- vue相关安装命令
安装cnpm npm install cnpm -g --registry=https://registry.npm.taobao.org
- myapplication 单例写法
MyApplication extends Application private static MyApplication myApplication = null; oncreate中: @Ove ...
- Web API: Client: HttpClient Message Handlers
原文地址: http://www.asp.net/web-api/overview/web-api-clients/httpclient-message-handlers using System; ...
- [转载].net程序集自动生成版本号
原文:http://hi.baidu.com/bcbgrand/item/a74a7ba71c3b0ea928ce9dce .net程序版本号的格式是4个十进制数字 比如 2.5.729.2 依次是 ...
- just test css
沃尔沃而 public void Commit() { if (_disposed) throw new InvalidOperationException(); if (_transaction = ...
- Redis(Remote Dictionary Server)入门
说说特性 存储结构:键值对支持多种数据类型,包括字符串类型,散列类型,列表类型,集合类型,有序集合类型. 内存存储与持久化:支持将内存中的数据异步写入磁盘中. 丰富的功能:支持为每个键值对设置生存时间 ...
- 如何使用Defender优雅的管理权限?
何为权限管理 权限管理已经不知不觉深入到了我们生活的每一个角落,例如地铁进站的闸机,高速公路上的过路费,停车场的杠杆等等等等. 作为一名开发人员,权限二字对我们的映像更加深刻,无论任何系统,都多多少少 ...
- 【leetcode 简单】 第九十题 字符串中的第一个唯一字符
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引.如果不存在,则返回 -1. 案例: s = "leetcode" 返回 0. s = "loveleetcod ...
- 2016.5.14——leetcode-HappyNumber,House Robber
leetcode:HappyNumber,House Robber 1.Happy Number 这个题中收获2点: 1.拿到题以后考虑特殊情况,代码中考虑1和4,或者说<6的情况,动手算下.( ...
- aarch64_l1
L-function-1.23-18.fc26.aarch64.rpm 2017-02-14 08:01 139K fedora Mirroring Project L-function-devel- ...