空降题目处(外网)
点我点我点我
空降题目处(内网)
点我点我点我
Description
笨笨当了很久的道路调度员,笨笨也开始想体验生活,从生活中发现数学问题,锻炼自己思维。最近《变形金刚3》,《哈利波特7》同步放映,明显是决战雌雄,已知王府井中一共有n人买了《变形金刚3》的票,m人买了《哈利波特7》的票,并且n>=m,并且电影院中现在只有两种票,每次只有一个人买,(共有n+m次),这n+m次组成一个排列,为了保证每一个人买票时,《变形金刚3》票房都不少于《哈利波特7》,(n个买《变形金刚3》的人之间没区别,m个买《哈利波特7》的人也没区别),笨笨想着到这样的购票方案有多少种。笨笨想了好久都没想出来,所以笨笨找到了你。
Input
一行两个数n,m ( 0<=m<=n<=5000)
Output
输出方案种数
Solution
套上神器的公式:
Ans=(N+2)×(N+3)×⋯×(N+M−1)×(N+M)×(N+1−M)M!
此处不予证明.
Code
C++
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#define F(i,x,y) for(long long i=x;i<=y;++i)
using namespace std;
struct node
{
int len,a[3500];
node()
{
len=1;
}
};
int num=0;
int prime[1501],a[10010];
int isNotPrime[10010] = {1, 1};
node chengfa_x(node n1,int x)
{
int i;node no;
no.len=n1.len;
for(i=1;i<=no.len;i++) no.a[i]=n1.a[i]*x;
for(i=1;i<=no.len;i++)
{
no.a[i+1]+=no.a[i]/10;
no.a[i]%=10;
}
i=no.len;
while(no.a[i+1]>0)
{
i++;
no.a[i+1]+=no.a[i]/10;
no.a[i]%=10;
}
while(no.a[i]==0&&i>1) i--;
no.len=i;
return no;
}
void workcheng(int x)
{
int t=x;
F(i,0,num)
{
while(t%prime[i]==0)
{
t/=prime[i];
a[i]++;
}
if(t<=1) break;
}
}
void workchu(int x)
{
int t=x;
F(i,0,num)
{
while(t%prime[i]==0)
{
t/=prime[i];
a[i]--;
}
if(t<=1) break;
}
}
int main()
{
int i,j,r,n,m,k,l,w;
node ans;
ans.a[1]=1;
scanf("%d%d",&n,&m);
for(long i = 2 ; i < 10000 ; i ++)
{
if(! isNotPrime[i]) prime[num++]=i;
for(long j = 0 ; j < num && i * prime[j] < 10000 ; j ++)
{
isNotPrime[i * prime[j]] = 1;
if( !(i % prime[j])) break;
}
}
F(i,2,m) workcheng(n+i);
workcheng(n+1-m);
F(i,2,m) workchu(i);
F(i,0,num)
{
F(j,1,a[i]) ans=chengfa_x(ans,prime[i]);
}
for(i=ans.len;i>=1;i--) printf("%d",ans.a[i]);
return 0;
}
Pascal
type
hp=array [0..3000] of int64;
var
ans:hp;
i,n,m:longint;
function times(x:hp;y:longint):hp;
var
i:longint;
begin
fillchar(times,sizeof(times),0);
for i:=1 to x[0] do
begin
inc(times[i],x[i]*y);
times[i+1]:=times[i] div 10000000;
times[i]:=times[i] mod 10000000;
end;
times[0]:=x[0];
if times[x[0]+1]<>0 then
inc(times[0]);
end;
function divide(x:hp;y:longint):hp;
var
i,t:longint;
begin
fillchar(divide,sizeof(divide),0);
t:=0;
for i:=x[0] downto 1 do
begin
divide[i]:=(x[i]+t*10000000) div y;
t:=(x[i]+t*10000000) mod y;
end;
divide[0]:=x[0];
while divide[divide[0]]=0 do
dec(divide[0]);
end;
procedure print(x:hp);
var
i,j:longint;
begin
write(x[x[0]]);
for i:=x[0]-1 downto 1 do
begin
j:=1000000;
while (x[i]<j) and (j>1) do
begin
write(0);
j:=j div 10;
end;
write(x[i]);
end;
writeln;
end;
begin
readln(n,m);
ans[0]:=1;
ans[1]:=n+1-m;
for i:=n+2 to n+m do
ans:=times(ans,i);
for i:=1 to m do
ans:=divide(ans,i);
print(ans);
end.