• BZOJ2729:[HNOI2012]排队(组合数学)


    Description

    某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检。他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的)
     

    Input

    只有一行且为用空格隔开的两个非负整数 n m,其含义如上所述。
     
    对于 30%的数据 n≤100,m≤100
     
    对于 100%的数据 n≤2000,m≤2000

    Output

    输出文件 output.txt 仅包含一个非负整数,表示不同的排法个数。注意答案可能很大。

    Sample Input

    1 1

    Sample Output

    12

    Solution

    一种情况是两个老师中间只有一个人且这个人是女生。

    即$A(n,n)*A(n+1,1)*A(2,2)*A(m,1)*A(n+2,m-1)$

    另一种情况是两个老师中间不是只有一个女生,也就是两个老师中间一定有男生。

    即$A(n,n)*A(n+1,2)*A(n+3,m)$

    Code

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<algorithm>
      6 #define MAX_L 20005
      7 using namespace std;
      8 
      9 class bign
     10 {
     11     public:
     12         int len, s[MAX_L];
     13         bign();
     14         bign(const char*);
     15         bign(int);
     16         bool sign;
     17         string toStr() const;
     18         friend istream& operator>>(istream &,bign &);
     19         friend ostream& operator<<(ostream &,bign &);
     20         bign operator=(const char*);
     21         bign operator=(int);
     22         bign operator=(const string);
     23         bool operator>(const bign &) const;
     24         bool operator>=(const bign &) const;
     25         bool operator<(const bign &) const;
     26         bool operator<=(const bign &) const;
     27         bool operator==(const bign &) const;
     28         bool operator!=(const bign &) const;
     29         bign operator+(const bign &) const;
     30         bign operator++();
     31         bign operator++(int);
     32         bign operator+=(const bign&);
     33         bign operator-(const bign &) const;
     34         bign operator--();
     35         bign operator--(int);
     36         bign operator-=(const bign&);
     37         bign operator*(const bign &)const;
     38         bign operator*(const int num)const;
     39         bign operator*=(const bign&);
     40         bign operator/(const bign&)const;
     41         bign operator/=(const bign&);
     42         bign operator%(const bign&)const;
     43         bign factorial()const;
     44         bign Sqrt()const;
     45         bign pow(const bign&)const;
     46         void clean();
     47         ~bign();
     48 };
     49 
     50 bign::bign()
     51 {
     52     memset(s,0,sizeof(s));
     53     len=1;
     54     sign=1;
     55 }
     56 
     57 bign::bign(const char *num)
     58 {
     59     *this=num;
     60 }
     61 
     62 bign::bign(int num)
     63 {
     64     *this=num;
     65 }
     66 
     67 string bign::toStr() const
     68 {
     69     string res;
     70     res="";
     71     for (int i=0; i<len; i++)
     72         res=(char)(s[i]+'0')+res;
     73     if (res=="")
     74         res="0";
     75     if (!sign&&res!="0")
     76         res="-"+res;
     77     return res;
     78 }
     79 
     80 istream &operator>>(istream &in, bign &num)
     81 {
     82     string str;
     83     in>>str;
     84     num=str;
     85     return in;
     86 }
     87 
     88 ostream &operator<<(ostream &out, bign &num)
     89 {
     90     out<<num.toStr();
     91     return out;
     92 }
     93 
     94 bign bign::operator=(const char *num)
     95 {
     96     memset(s,0,sizeof(s));
     97     char a[MAX_L]="";
     98     if (num[0]!='-')
     99         strcpy(a,num);
    100     else
    101         for (int i=1,l=strlen(num); i<l; i++)
    102             a[i-1]=num[i];
    103     sign=!(num[0]=='-');
    104     len=strlen(a);
    105     for (int i=0; i<strlen(a); i++)
    106         s[i]=a[len-i-1]-48;
    107     return *this;
    108 }
    109 
    110 bign bign::operator=(int num)
    111 {
    112     char temp[MAX_L];
    113     sprintf(temp,"%d",num);
    114     *this=temp;
    115     return *this;
    116 }
    117 
    118 bign bign::operator=(const string num)
    119 {
    120     const char *tmp;
    121     tmp=num.c_str();
    122     *this=tmp;
    123     return *this;
    124 }
    125 
    126 bool bign::operator<(const bign &num) const
    127 {
    128     if (sign^num.sign)
    129         return num.sign;
    130     if (len!=num.len)
    131         return len<num.len;
    132     for (int i=len-1; i>=0; i--)
    133         if (s[i]!=num.s[i])
    134             return sign?(s[i]<num.s[i]):(!(s[i]<num.s[i]));
    135     return !sign;
    136 }
    137 
    138 bool bign::operator>(const bign&num)const
    139 {
    140     return num<*this;
    141 }
    142 
    143 bool bign::operator<=(const bign&num)const
    144 {
    145     return !(*this>num);
    146 }
    147 
    148 bool bign::operator>=(const bign&num)const
    149 {
    150     return !(*this<num);
    151 }
    152 
    153 bool bign::operator!=(const bign&num)const
    154 {
    155     return *this>num || *this<num;
    156 }
    157 
    158 bool bign::operator==(const bign&num)const
    159 {
    160     return !(num!=*this);
    161 }
    162 
    163 bign bign::operator+(const bign &num) const
    164 {
    165     if (sign^num.sign)
    166     {
    167         bign tmp=sign?num:*this;
    168         tmp.sign=1;
    169         return sign?*this-tmp:num-tmp;
    170     }
    171     bign result;
    172     result.len=0;
    173     int temp=0;
    174     for (int i=0; temp || i<(max(len, num.len)); i++)
    175     {
    176         int t=s[i]+num.s[i]+temp;
    177         result.s[result.len++]=t % 10;
    178         temp=t/10;
    179     }
    180     result.sign=sign;
    181     return result;
    182 }
    183 
    184 bign bign::operator++()
    185 {
    186     *this=*this+1;
    187     return *this;
    188 }
    189 
    190 bign bign::operator++(int)
    191 {
    192     bign old=*this;
    193     ++(*this);
    194     return old;
    195 }
    196 
    197 bign bign::operator+=(const bign &num)
    198 {
    199     *this=*this+num;
    200     return *this;
    201 }
    202 
    203 bign bign::operator-(const bign &num) const
    204 {
    205     bign b=num,a=*this;
    206     if (!num.sign && !sign)
    207     {
    208         b.sign=1;
    209         a.sign=1;
    210         return b-a;
    211     }
    212     if (!b.sign)
    213     {
    214         b.sign=1;
    215         return a+b;
    216     }
    217     if (!a.sign)
    218     {
    219         a.sign=1;
    220         b=bign(0)-(a+b);
    221         return b;
    222     }
    223     if (a<b)
    224     {
    225         bign c=(b-a);
    226         c.sign=false;
    227         return c;
    228     }
    229     bign result;
    230     result.len=0;
    231     for (int i=0, g=0; i<a.len; i++)
    232     {
    233         int x=a.s[i]-g;
    234         if (i<b.len) x -= b.s[i];
    235         if (x >= 0) g=0;
    236         else
    237         {
    238             g=1;
    239             x += 10;
    240         }
    241         result.s[result.len++]=x;
    242     }
    243     result.clean();
    244     return result;
    245 }
    246 
    247 bign bign::operator * (const bign &num)const
    248 {
    249     bign result;
    250     result.len=len+num.len;
    251 
    252     for (int i=0; i<len; i++)
    253         for (int j=0; j<num.len; j++)
    254             result.s[i+j] += s[i] * num.s[j];
    255 
    256     for (int i=0; i<result.len; i++)
    257     {
    258         result.s[i+1] += result.s[i]/10;
    259         result.s[i] %= 10;
    260     }
    261     result.clean();
    262     result.sign=!(sign^num.sign);
    263     return result;
    264 }
    265 
    266 bign bign::operator*(const int num)const
    267 {
    268     bign x=num;
    269     bign z=*this;
    270     return x*z;
    271 }
    272 bign bign::operator*=(const bign&num)
    273 {
    274     *this=*this * num;
    275     return *this;
    276 }
    277 
    278 bign bign::operator /(const bign&num)const
    279 {
    280     bign ans;
    281     ans.len=len-num.len+1;
    282     if (ans.len<0)
    283     {
    284         ans.len=1;
    285         return ans;
    286     }
    287 
    288     bign divisor=*this, divid=num;
    289     divisor.sign=divid.sign=1;
    290     int k=ans.len-1;
    291     int j=len-1;
    292     while (k >= 0)
    293     {
    294         while (divisor.s[j]==0) j--;
    295         if (k > j) k=j;
    296         char z[MAX_L];
    297         memset(z, 0, sizeof(z));
    298         for (int i=j; i >= k; i--)
    299             z[j-i]=divisor.s[i]+'0';
    300         bign dividend=z;
    301         if (dividend<divid)
    302         {
    303             k--;
    304             continue;
    305         }
    306         int key=0;
    307         while (divid*key <= dividend) key++;
    308         key--;
    309         ans.s[k]=key;
    310         bign temp=divid*key;
    311         for (int i=0; i<k; i++)
    312             temp=temp * 10;
    313         divisor=divisor-temp;
    314         k--;
    315     }
    316     ans.clean();
    317     ans.sign=!(sign^num.sign);
    318     return ans;
    319 }
    320 
    321 bign bign::operator/=(const bign&num)
    322 {
    323     *this=*this/num;
    324     return *this;
    325 }
    326 
    327 bign bign::operator%(const bign& num)const
    328 {
    329     bign a=*this, b=num;
    330     a.sign=b.sign=1;
    331     bign result, temp=a/b*b;
    332     result=a-temp;
    333     result.sign=sign;
    334     return result;
    335 }
    336 
    337 bign bign::pow(const bign& num)const
    338 {
    339     bign result=1;
    340     for (bign i=0; i<num; i++)
    341         result=result*(*this);
    342     return result;
    343 }
    344 
    345 bign bign::factorial()const
    346 {
    347     bign result=1;
    348     for (bign i=1; i <= *this; i++)
    349         result*=i;
    350     return result;
    351 }
    352 
    353 void bign::clean()
    354 {
    355     if (len==0) len++;
    356     while (len>1 && s[len-1]=='')
    357         len--;
    358 }
    359 
    360 bign bign::Sqrt()const
    361 {
    362     if(*this<0)return -1;
    363     if(*this<=1)return *this;
    364     bign l=0,r=*this,mid;
    365     while(r-l>1)
    366     {
    367         mid=(l+r)/2;
    368         if(mid*mid>*this) r=mid;
    369         else l=mid;
    370     }
    371     return l;
    372 }
    373 
    374 bign::~bign()
    375 {
    376 }
    377 
    378 bign A(int n,int m)
    379 {
    380     bign ans;
    381     ans=1;
    382     for (int i=n-m+1; i<=n; ++i) ans*=i;
    383     return ans;
    384 }
    385 
    386 int n,m; 
    387 
    388 int main()
    389 {
    390     scanf("%d%d",&n,&m);
    391     bign ans=A(n,n)*A(n+1,2)*A(n+3,m)+A(n,n)*A(n+1,1)*A(2,2)*A(m,1)*A(n+2,m-1);
    392     cout<<ans;
    393 }
  • 相关阅读:
    Python面向对象-类成员
    python面向对象-继承
    Linux 静态和动态添加路由
    Linux 添加虚拟网卡
    centos7源码包安装Mongodb,并设置开机自启动
    centos7配置静态ip地址
    Python开发【前端篇】JavaScript和Jquery
    Python爬虫【解析库之pyquery】
    Python爬虫 selenium
    Python爬虫【解析库之beautifulsoup】
  • 原文地址:https://www.cnblogs.com/refun/p/10086487.html
Copyright © 2020-2023  润新知