zoukankan      html  css  js  c++  java
  • 2016百度之星资格赛 Problem B(大数+组合数)

      题意:度熊面前有一个全是由1构成的字符串,被称为全1序列。你可以合并任意相邻的两个1,从而形成一个新的序列。对于给定的一个全1序列,请计算根据以上方法,可以构成多少种不同的序列。最多200个1。

      比如:如果序列是:(111)。可以构造出如下三个新序列:(111), (21), (12)。

      分析:对于任意的相邻的两个1合并,那么总的个数就会减1,然后把2放在任意一个位置,也就是说,如果有x个2,那么总的数字个数就是n-x,相当于在这n-x中选择x个变成2,那么显然是组合数求解,在枚举x的个数即可。

      但是,考虑到最大范围是200,会超long long,所以直接套大数模板就可以了。

      下面是AC代码:

      1 #include<stdio.h>
      2 #include<string>
      3 #include<string.h>
      4 #include<iostream>
      5 using namespace std;
      6 
      7 //compare比较函数:相等返回0,大于返回1,小于返回-1
      8 int compare(string str1,string str2)
      9 {
     10     if(str1.length()>str2.length()) return 1;
     11     else if(str1.length()<str2.length())  return -1;
     12     else return str1.compare(str2);
     13 }
     14 //高精度加法
     15 //只能是两个正数相加
     16 string add(string str1,string str2)//高精度加法
     17 {
     18     string str;
     19 
     20     int len1=str1.length();
     21     int len2=str2.length();
     22     //前面补0,弄成长度相同
     23     if(len1<len2)
     24     {
     25         for(int i=1;i<=len2-len1;i++)
     26            str1="0"+str1;
     27     }
     28     else
     29     {
     30         for(int i=1;i<=len1-len2;i++)
     31            str2="0"+str2;
     32     }
     33     len1=str1.length();
     34     int cf=0;
     35     int temp;
     36     for(int i=len1-1;i>=0;i--)
     37     {
     38         temp=str1[i]-'0'+str2[i]-'0'+cf;
     39         cf=temp/10;
     40         temp%=10;
     41         str=char(temp+'0')+str;
     42     }
     43     if(cf!=0)  str=char(cf+'0')+str;
     44     return str;
     45 }
     46 //高精度减法
     47 //只能是两个正数相减,而且要大减小
     48 string sub(string str1,string str2)//高精度减法
     49 {
     50     string str;
     51     int tmp=str1.length()-str2.length();
     52     int cf=0;
     53     for(int i=str2.length()-1;i>=0;i--)
     54     {
     55         if(str1[tmp+i]<str2[i]+cf)
     56         {
     57             str=char(str1[tmp+i]-str2[i]-cf+'0'+10)+str;
     58             cf=1;
     59         }
     60         else
     61         {
     62             str=char(str1[tmp+i]-str2[i]-cf+'0')+str;
     63             cf=0;
     64         }
     65     }
     66     for(int i=tmp-1;i>=0;i--)
     67     {
     68         if(str1[i]-cf>='0')
     69         {
     70             str=char(str1[i]-cf)+str;
     71             cf=0;
     72         }
     73         else
     74         {
     75             str=char(str1[i]-cf+10)+str;
     76             cf=1;
     77         }
     78     }
     79     str.erase(0,str.find_first_not_of('0'));//去除结果中多余的前导0
     80     return str;
     81 }
     82 //高精度乘法
     83 //只能是两个正数相乘
     84 string mul(string str1,string str2)
     85 {
     86     string str;
     87     int len1=str1.length();
     88     int len2=str2.length();
     89     string tempstr;
     90     for(int i=len2-1;i>=0;i--)
     91     {
     92         tempstr="";
     93         int temp=str2[i]-'0';
     94         int t=0;
     95         int cf=0;
     96         if(temp!=0)
     97         {
     98             for(int j=1;j<=len2-1-i;j++)
     99               tempstr+="0";
    100             for(int j=len1-1;j>=0;j--)
    101             {
    102                 t=(temp*(str1[j]-'0')+cf)%10;
    103                 cf=(temp*(str1[j]-'0')+cf)/10;
    104                 tempstr=char(t+'0')+tempstr;
    105             }
    106             if(cf!=0) tempstr=char(cf+'0')+tempstr;
    107         }
    108         str=add(str,tempstr);
    109     }
    110     str.erase(0,str.find_first_not_of('0'));
    111     return str;
    112 }
    113 
    114 //高精度除法
    115 //两个正数相除,商为quotient,余数为residue
    116 //需要高精度减法和乘法
    117 void div(string str1,string str2,string &quotient,string &residue)
    118 {
    119     quotient=residue="";//清空
    120     if(str2=="0")//判断除数是否为0
    121     {
    122         quotient=residue="ERROR";
    123         return;
    124     }
    125     if(str1=="0")//判断被除数是否为0
    126     {
    127         quotient=residue="0";
    128         return;
    129     }
    130     int res=compare(str1,str2);
    131     if(res<0)
    132     {
    133         quotient="0";
    134         residue=str1;
    135         return;
    136     }
    137     else if(res==0)
    138     {
    139         quotient="1";
    140         residue="0";
    141         return;
    142     }
    143     else
    144     {
    145         int len1=str1.length();
    146         int len2=str2.length();
    147         string tempstr;
    148         tempstr.append(str1,0,len2-1);
    149         for(int i=len2-1;i<len1;i++)
    150         {
    151             tempstr=tempstr+str1[i];
    152             tempstr.erase(0,tempstr.find_first_not_of('0'));
    153             if(tempstr.empty())
    154               tempstr="0";
    155             for(char ch='9';ch>='0';ch--)//试商
    156             {
    157                 string str,tmp;
    158                 str=str+ch;
    159                 tmp=mul(str2,str);
    160                 if(compare(tmp,tempstr)<=0)//试商成功
    161                 {
    162                     quotient=quotient+ch;
    163                     tempstr=sub(tempstr,tmp);
    164                     break;
    165                 }
    166             }
    167         }
    168         residue=tempstr;
    169     }
    170     quotient.erase(0,quotient.find_first_not_of('0'));
    171     if(quotient.empty()) quotient="0";
    172 }
    173 string c[205][205];
    174 void init()
    175 {
    176     for(int i=1;i<=200;i++)
    177         for(int j=1;j<=200;j++) c[i][j]="0";
    178     c[0][0]="1";
    179     c[1][0]=c[1][1]="1";
    180     for(int i=2;i<=200;i++)
    181     {
    182         for(int j=0;j<=i;j++)
    183         {
    184             if(j==0||j==i) c[i][j]="1";
    185             else c[i][j]=add(c[i][j],add(c[i-1][j],c[i-1][j-1]));
    186         }
    187     }
    188 }
    189 int main()
    190 {
    191     init();
    192      /*string str1,str2;
    193      string str3,str4;
    194      while(cin>>str1>>str2)
    195      {
    196          cout<<add(str1,str2)<<endl;
    197          cout<<sub(str1,str2)<<endl;
    198          cout<<mul(str1,str2)<<endl;
    199          div(str1,str2,str3,str4);
    200          cout<<str3<<"  "<<str4<<endl;
    201      }*/
    202      int n;
    203      while(scanf("%d",&n)==1)
    204      {
    205         string ans="0";
    206         for(int i=n;i>=(n+1)/2;i--)
    207         {
    208             ans=add(ans,c[i][n-i]);
    209         }
    210         cout<<ans<<endl;
    211      }
    212      return 0;
    213 }

    这是kuangbin的大数模板,以后就用这份模板好了- -

  • 相关阅读:
    C#写文本文件,如何换行(添加换行符)
    C#使用oledb操作excel文件的方法
    winform之combobox
    vs2010快捷键
    可以下载一些书籍代码的网站
    对php和java里面的static函数和static的一些理解
    10.4-CMake find 模块
    6.25-Git 技巧
    6.4-Git Command
    2.25-CMake Tutorial
  • 原文地址:https://www.cnblogs.com/zzyDS/p/5492836.html
Copyright © 2011-2022 走看看