zoukankan      html  css  js  c++  java
  • BZOJ4563:[HAOI2016]放棋子——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4563

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

    假设最开始棋子都放在障碍上,然后将所有行压成一行,那么下面的问题就是有多少种方法使得棋子不放在自己原来的位置上并且不能与别的棋子重合?

    这就是一个错排问题了,高精即可。

    #include<map>
    #include<cmath>
    #include<stack>
    #include<queue>
    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=10005;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    struct Bignum{//必须定义在main之外
        int a[N],len;
        Bignum(){
        memset(a,0,sizeof(a));len=0;
        }
        void print(){
        for(int i=len-1;i>=0;i--)putchar(a[i]+'0');
        putchar('
    ');
        }
        Bignum operator +(const Bignum &b)const{
        Bignum ans;ans.len=len;
        for(int i=0;i<ans.len;i++)ans.a[i]=a[i];
        for(int i=0;i<ans.len;i++){
            ans.a[i]+=b.a[i];
            if(ans.a[i]>9){
            ans.a[i]-=10;ans.a[i+1]++;
            if(i+1==ans.len)ans.len++;
            }
        }
        if(ans.len<b.len){
            for(int i=ans.len;i<b.len;i++)ans.a[i]=b.a[i];
            ans.len=b.len;
        }
        return ans;
        }
        Bignum operator *(const int &b)const{
        Bignum ans;ans.len=len;
        for(int i=0;i<ans.len;i++)ans.a[i]=a[i]*b;
        for(int i=0;i<ans.len;i++){
            if(ans.a[i]>9){
            ans.a[i+1]+=ans.a[i]/10;ans.a[i]%=10;
            if(i+1==ans.len)ans.len++;
            }
        }
        return ans;
        }
    }d1,d2;
    int n;
    int main(){
        n=read();
        if(n==1){puts("0");return 0;}
        if(n==2){puts("1");return 0;}
        d1.a[0]=0;d1.len=1;
        d2.a[0]=1;d2.len=1;
        for(int i=3;i<=n;i++){
        Bignum ans=(d2+d1)*(i-1);
        swap(d1,d2);swap(d2,ans);
        }
        d2.print();
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

    +本文作者:luyouqi233。               +

    +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    怎么接音响
    怎样区分音箱与音响
    什么是卡盟
    小白晋级达人必备 电视接口使用介绍(4)
    液晶电视插有线电视信号线的是哪个接口 HDMI是什么接口
    Google 镜像站搜集
    屏幕检测
    网站引流
    夜神安卓模拟器
    html5模拟平抛运动
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/9197744.html
Copyright © 2011-2022 走看看