zoukankan      html  css  js  c++  java
  • bzoj4563: [Haoi2016]放棋子(错排+高精)

    4563: [Haoi2016]放棋子

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 387  Solved: 247
    [Submit][Status][Discuss]

    Description

    给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在
    这个矩阵上放N枚棋子(障碍的位置不能放棋子),要求你放N个棋子也满足每行只有一枚棋子,每列只有一枚棋子
    的限制,求有多少种方案。
     

     

    Input

    第一行一个N,接下来一个N*N的矩阵。N<=200,0表示没有障碍,1表示有障碍,输入格式参考样例
     

     

    Output

    一个整数,即合法的方案数。

     

    Sample Input

    2
    0 1
    1 0

    Sample Output

    1
     
    /*
    每一行每一列只能放1个求方案数 转化为错排问题
    练习高精压位 压9位。。。
    */
    #include <iostream>
    #include <cstdio>
    #include<iomanip>
    
    #define N 2001
    #define mod 1000000000
    #define _ 9
    #define ll long long
    
    using namespace std;
    ll n;
    struct num
    {
        ll d[N],w;
    /*    void print()
        {
            for (ll i=w;i>=1;i--) cout<<d[i];
            printf("
    ");
        }*/
    }D[N],id;
    
    num operator +(num p1,num p2)
    {
        num ret=id;
        ll g=0;
        if (p1.w<p2.w) swap(p1,p2);
        ret.w=p1.w;
        for (ll i=1;i<=p1.w;i++)
        {
            ret.d[i]=(p1.d[i]+p2.d[i]+g)%mod;
            g=(p1.d[i]+p2.d[i]+g)/mod;
        }
        while(g) ret.d[++ret.w]=g%mod , g/=mod;
        return ret;
    }
    
    num mul(num p1,ll p2)
    {
        num ret=id;
        ret.w=p1.w;
        ll g=0;
        for (ll i=1;i<=p1.w;i++)
        {
            ret.d[i]=(p1.d[i]*p2+g)%mod;
            g=(p1.d[i]*p2+g)/mod;
        }
        while(g) ret.d[++ret.w]=g%mod,g/=mod;
        return ret;
    }
    
    ostream& operator << (ostream &os,num x)
    {
        ll i;
        os<<x.d[x.w];
        for(i=x.w-1;i;i--)
            os<<setfill('0')<<setw(_)<<x.d[i];
        return os;
    }
    
    int main()
    {
        scanf("%d",&n);
        if (n == 1)
        {
            puts("0");
            return 0;
        }
        D[1]=id;
        D[2].w=D[2].d[1]=1;
        for (ll i=3;i<=n;i++)
          D[i] = mul((D[i-1]+D[i-2]),i-1);
        cout<<D[n];
        return 0;
    }
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    有向图的强连通分量——tarjan
    最小生成树——Kruskal算法
    最小生成树——Prim算法
    递归的正确切入方法
    大整数类概述
    初涉算法——STL初步
    初涉算法——C++
    ACM常用模板
    ACM入门步骤(一)
    划分树
  • 原文地址:https://www.cnblogs.com/L-Memory/p/7551892.html
Copyright © 2011-2022 走看看