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的大数模板,以后就用这份模板好了- -

原文地址:https://www.cnblogs.com/zzyDS/p/5492836.html