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 ...
随机推荐
- Android 使用GPS获取到经纬度后 无法在Android8.0上使用Geocoder类获取位置信息
由于我的应用在获取到经纬度后在Android8.0不能使用如下代码获取位置信息.只好使用百度地图 WEB服务API 通过调接口的方式获取位置信息. Geocoder geocoder = new Ge ...
- 洛谷P1456 Monkey King
https://www.luogu.org/problemnew/show/1456 #include<cstdio> #include<iostream> #include& ...
- [转载]mysql下载安装
转自https://www.cnblogs.com/tyhj-zxp/p/6693046.html 下载 打开:https://www.mysql.com/downloads/ 1.点击该项:
- Spyder简述
导言 想打造轮子, 就必须要有一套完善的造轮子的工具. 我在jupyter+sciTE的组合里转来转去, 最后还是打算放弃这个组合, 因为离开了自动完成/调用提示/随时随地的访问文档帮助, 前行之路太 ...
- [转载]jsonp详解
http://www.cnblogs.com/lemontea/archive/2012/12/11/2812268.html json相信大家都用的多,jsonp我就一直没有机会用到,但也经常看到, ...
- Spring3.2 Contorller单元测试参数问题: java.lang.NoSuchMethodException
使用3.2做单元测试的时候发现这个问题,因为之前都是用3.0中的配置适配器使用AnnotationMethodHandlerAdapter,到3.2中升级为RequestMappingHandlerA ...
- 如何清理休眠文件(hiberfil.sys)
如果使用了休眠功能,那么打开系统盘就会有一个很大(5.36G)的hiberfil.sys文件,它是将用户正在运行的程序,保存在这里,再启动系统就很快了.如要清理它(不用休眠功能,或者临时腾出空间),可 ...
- python模块-platform
#author:Blood_Zero #coding:utf- import platform print dir(platform) #获取platform函数功能 platform.archite ...
- Solr管理索引库——(十三)
a) 维护索引 1. 添加/更新文档 添加或更新单个文档
- spring boot 测试用例
junit 是一个面向于研发人员使用的轻量的测试模块,适合做单元测试.而testng百度后发现更强大,可以做功能测试,但对于我这种RD,貌似junit足沟了呢! java Mock PowerMock ...