• HYSBZ 4563 放棋子


    题意:
    给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在这个矩阵上放N枚棋子(障碍的位置不能放棋子),要求你放N个棋子也满足每行只有一枚棋子,每列只有一枚棋子的限制,求有多少种方案。
    题解:⑥
    ①这道题我们可以分析为错排问题:
    一共 1~n n个数,对于任意数x都不在第x个位置上有多少方案数。
    ②为什么这么说呢(⊙o⊙)?
    ⑴我们可以注意到:每一行每一列有且只有一个障碍
    ⑵那么每一行障碍的位置对于答案没有任何实际影响
    ⑶如果我们按照每一行障碍的位置对行进行排序的话
    ⑷就转化成了第i行的棋子不能出现在第i个位置的问题
    ⑸也就是我们上面说的错排问题了
    ③那么错排问题的公式是什么呢?
    f[i]=f[i-1]*(i-1)+f[i-2]*(i-1)
    ④原理:
    ⑴第一步,把第i个元素放在一个位置,比如位置k,一共有i-1种方法
    ⑵第二步,放编号为k的元素,这时有两种情况:
    ⒈把它放到位置i,那么,对于剩下的i-1个元素,由于第k个元素放到了位置i,剩下i-2个元素就有f[i-2]种方法
    ⒉第k个元素不把它放到位置i,这时,对于这i-1个元素,有f[i-1]种方法

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <iostream>
    #include <string.h>
    using namespace std;
    struct BigInteger{
        int s[1005],len;
        BigInteger(){
            len=0;
            memset(s,0,sizeof(s));
        }
        BigInteger(const char *A){*this=A;}
        BigInteger(const int &A){*this=A;}
        void operator=(const char *A){
            len=strlen(A);
            for(int i=0;i<len;i++)
                s[i]=A[len-i-1]-'0';
        }
        void operator=(const int &A){
            char tmp[1005];
            memset(tmp,0,sizeof(tmp));
            sprintf(tmp,"%d",A);
            *this=tmp;
        }
        void clear(){
            while(len>1 && !s[len-1])len--;
        }
        BigInteger operator+(const BigInteger &A){
            BigInteger ans;
            ans.len=max(len,A.len)+1;
            int Carry=0;
            for(int i=0;i<len;i++){
                ans.s[i]=s[i]+A.s[i]+Carry;
                Carry=ans.s[i]/10;
                ans.s[i]%=10;
            }
            if(Carry)ans.s[len++]=Carry;
            ans.clear();
            return ans;
        }
        void operator+=(const BigInteger &A){
            *this=*this+A;
        }
        BigInteger operator-(const BigInteger &A){
            BigInteger ans;
            ans=*this;
            for(int i=0;i<len;i++){
                if(ans.s[i]<A.s[i])
                    ans.s[i]+=10,ans.s[i+1]--;
                ans.s[i]=ans.s[i]-A.s[i];
            }
            ans.clear();
            return ans;
        }
        void operator-=(const BigInteger &A){
            *this=*this-A;
        }
        BigInteger operator-(const int &A){
            BigInteger tmp=A;
            return *this-tmp;
        }
        void operator-=(const int &A){
            *this=*this-A;
        }
        BigInteger operator*(const BigInteger &A){
            BigInteger ans;
            ans.len=len+A.len+1;
            int Carry=0;
            for(int i=0;i<len;i++){
                Carry=0;
                for(int j=0;j<A.len;j++){
                    ans.s[i+j]+=s[i]*A.s[j]+Carry;
                    Carry=ans.s[i+j]/10;
                    ans.s[i+j]%=10;
                }
                ans.s[i+A.len]+=Carry;
            }
            ans.clear();
            return ans;
        }
        void operator*=(const BigInteger &A){
            *this=*this*A;
        }
        BigInteger operator*(const int &A){
            BigInteger tmp=A;
            return *this*tmp;
        }
        void operator*=(const int &A){
            *this=*this*A;
        }
        void Print(){
            for(int i=len-1;i>=0;i--)
                printf("%d",s[i]);
            printf("
    ");
        }
    }f[205];
    int main(){
        int n;scanf("%d",&n);
        f[0]=1;
        f[1]=0;
        for(int i=2;i<=n;i++)
            f[i]=(f[i-1]+f[i-2])*(i-1);
        f[n].Print();
        return 0;
    }

     

  • 相关阅读:
    如何在EasyDSS内调用的iframe地址设置自动播放?
    雏鹰训练营第一次作业
    211806152 蔡钰玲 http://www.cnblogs.com/211806152Erika/ https://github.com/ErikaSakii
    Python05:while循环
    Python04:简单if逻辑判断
    Python03:用户交互输入格式输出
    Python02:变量
    Python01:HelloWorld
    课后作业(一)
    软工假期预先作业
  • 原文地址:https://www.cnblogs.com/holy-unicorn/p/9510285.html
Copyright © 2020-2023  润新知