zoukankan      html  css  js  c++  java
  • 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反正我是想不到的
     1 /*
     2 LANG: C++
     3 PROG: latin
     4 */
     5 #include <iostream>
     6 #include <cstdio>
     7 #include <algorithm>
     8 #include <cstring>
     9 #include <cmath>
    10 #define siji(i,x,y) for(int i=(x); i<=(y) ; ++i)
    11 #define ivorysi
    12 #define o(x) ((x)*(x))
    13 using namespace std;
    14 typedef long long ll;
    15 int n;
    16 int col[10],row[10],num[10][10];
    17 bool v[10];
    18 ll ans,h[50][5];//置换圈的长度乘积,个数
    19 void init() {
    20     scanf("%d",&n);
    21     siji(i,1,n) {
    22         num[1][i]=i;
    23         num[i][1]=i;
    24         col[i]=(1<<i);
    25         row[i]=(1<<i);
    26     }
    27     memset(h,-1,sizeof(h));
    28 }
    29 
    30 ll dfs(int x,int y) {
    31     if(x>=n){
    32         return 1;
    33     }
    34     ll res=0;
    35     if(x==3&&y==2) {
    36         memset(v,0,sizeof(v));
    37         int cnt=0,len=1;
    38         siji(i,1,n) {
    39             if(v[i]) continue;
    40             v[i]=1;
    41             int rec=1;
    42             for(int l=num[2][i];l!=i;l=num[2][l]) {
    43                 v[l]=1;
    44                 ++rec;
    45             }
    46             len*=rec;
    47             ++cnt;
    48         }
    49         if(h[len][cnt]!=-1) return h[len][cnt];
    50         siji(i,1,n) {
    51             if(((col[y]&(1<<i))==0) && ((row[x]&(1<<i))==0)) {
    52                 col[y]|=(1<<i);
    53                 row[x]|=(1<<i);
    54                 num[x][y]=i;
    55                 if(y==n) res+=dfs(x+1,2);
    56                 else res+=dfs(x,y+1);
    57                 col[y]^=(1<<i);
    58                 row[x]^=(1<<i);
    59                 num[x][y]=0;
    60             }
    61         }
    62         return h[len][cnt]=res;
    63     }
    64     siji(i,1,n) {
    65         if(((col[y]&(1<<i))==0) && ((row[x]&(1<<i))==0)) {
    66             col[y]|=(1<<i);
    67             row[x]|=(1<<i);
    68             num[x][y]=i;
    69             if(y==n) res+=dfs(x+1,2);
    70             else res+=dfs(x,y+1);
    71             col[y]^=(1<<i);
    72             row[x]^=(1<<i);
    73             num[x][y]=0;
    74         }
    75     }
    76     return res;
    77 }
    78 void solve() {
    79     init();
    80     //if(n==7) {cout<<"12198297600"<<endl;return;}
    81     ans=dfs(2,2);
    82     siji(i,1,n-1) ans*=i;
    83     printf("%lld
    ",ans);
    84 }
    85 int main(int argc, char const *argv[])
    86 {
    87 #ifdef ivorysi
    88     freopen("latin.in","r",stdin);
    89     freopen("latin.out","w",stdout);
    90 #else
    91     freopen("f1.in","r",stdin);
    92     //freopen("f1.out","w",stdout);
    93 #endif
    94     solve();
    95     return 0;
    96 }
  • 相关阅读:
    数据预处理
    机器学习--有监督学习和无监督学习
    weka简介
    第10章 接口、继承与多态----类的继承3
    html5 canvas实现梦幻的3D刺猬球
    html5 canvas实现图片玻璃碎片特效
    css3实现的鼠标经过按钮特效
    CSS3 Transitions属性打造动画的下载按钮特效
    纯css3实现的幽灵按钮导航
    几行css3代码实现超炫加载动画
  • 原文地址:https://www.cnblogs.com/ivorysi/p/6938634.html
Copyright © 2011-2022 走看看