3 条题解
-
2
直接由 N老师 得到的式子进行高精,赤石!!!
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #define int long long #define N 15005 using namespace std; bool Test_MLE_start; int T=1,n,m; int La1,La2,La4,La5,La6,Lc31,Lc32,Lc71,Lc72,Lc3,Lc7,Lp1,Lp2,Lans; int a1[N],a2[N],a4[N],a5[N],a6[N],c31[N],c32[N],c71[N],c72[N],c3[N],c7[N]; int c[N],p[N],ans[N],tmp[N],p1[N],p2[N],t[N]; bool Test_MLE_end; inline int reads(){ char c=getchar(); int sum=0,f=1; while(!isdigit(c)){ if(c=='-') f=-1; c=getchar(); } while(isdigit(c)){ sum=(sum<<3)+(sum<<1)+(c-'0'); c=getchar(); } return sum*f; } inline void files(){ // freopen("std.in","r",stdin); freopen("std.out","w",stdout); } inline void clr(){ // Don't forget! a1[1]=a2[1]=c31[1]=c32[1]=a4[1]=a5[1]=a6[1]=c71[1]=c72[1]=1; La1=La2=Lc31=Lc32=La4=La5=La6=Lc71=Lc72=1; } void print(int a[],int La){ for(int i=La;i>=1;i--) cout<<a[i]; puts(""); } void mul(int a[],int b[],int c[],int La,int Lb,int &Lc){ for(int i=1;i<=Lb;i++){ int x=0; for(int j=1;j<=La;j++){ c[j+i-1]=a[j]*b[i]+x+c[i+j-1]; x=c[i+j-1]/10; c[i+j-1]%=10; } c[i+La]=x; } Lc=La+Lb; while(c[Lc]==0&&Lc>1) Lc--; return; } void fac(int a[],int n,int m,int &La){ for(int ppp=n;ppp<=m;ppp++){ int now=ppp,cnt=0; memset(p,0,sizeof(p)),memset(c,0,sizeof(c)); while(now){ int x=now%10; now/=10; p[++cnt]=x; } for(int i=1;i<=cnt;i++){ int x=0; for(int j=1;j<=La;j++){ c[j+i-1]=a[j]*p[i]+x+c[i+j-1]; x=c[i+j-1]/10; c[i+j-1]%=10; } c[i+La]=x; } for(int i=1;i<=La+cnt;i++) a[i]=c[i]; La+=cnt; while(!a[La]&&La>1) La--; } } int compare(int a[],int b[]){ if(a[0]>b[0]) return 1; if(a[0]<b[0]) return -1; for(int i=a[0];i>0;i--){ if(a[i]>b[i]) return 1; if(a[i]<b[i]) return -1; } return 0; } void jian(int a[],int b[]){ int flag; flag=compare(a,b); if(flag==0){ a[0]=0; return; } if(flag==1){ for(int i=1;i<=a[0];i++){ if(a[i]<b[i]){ a[i+1]--; a[i]=a[i]+10; } a[i]-=b[i]; } while(a[0]>0&&a[a[0]]==0){ a[0]--; } return; } } void numcpy(int p[],int q[],int det){ for(int i=1;i<=p[0];i++) q[i+det-1]=p[i]; q[0]=p[0]+det-1; return; } void chugao(int a[],int b[],int c[],int La,int Lb,int &Lc){ a[0]=La,b[0]=Lb; c[0]=a[0]-b[0]+1; for(int i=c[0];i>0;i--){ memset(tmp,0,sizeof(tmp)); numcpy(b,tmp,i); while(compare(a,tmp)>=0){ c[i]++; jian(a,tmp); } } while(c[0]>0&&c[c[0]]==0) c[0]--; Lc=c[0]; return; } void cheng(int a[],int b[],int &La,int Lb,int Lc){ int Lt=La; if(!La) Lt=1,t[1]=1; else for(int i=1;i<=La;i++) t[i]=a[i]; memset(a,0,sizeof(a)); for(int i=1;i<=La;i++) a[i]=0; La=0; mul(t,b,a,Lt,Lb,La); } void jian2(int a1[],int b1[],int c1[],int La){ int x=0; for(int i=1;i<=La;i++){ c1[i]=a1[i]-b1[i]-x; if(c1[i]<0){ c1[i]+=10; x=1; } else x=0; } return; } signed main(){ // printf("%lf Mb\n",(&Test_MLE_end-&Test_MLE_start-1)/1024.0/1024.0); // files(); // T=reads(); while(T--){ n=reads(),m=reads(); clr(); fac(a1,1,n+2,La1); fac(a2,1,m,La2); fac(c31,n+3-m+1,n+3,Lc31),fac(c32,1,m,Lc32); chugao(c31,c32,c3,Lc31,Lc32,Lc3); cheng(p1,a1,Lp1,La1,Lp1),cheng(p1,a2,Lp1,La2,Lp1),cheng(p1,c3,Lp1,Lc3,Lp1); fac(a4,1,2,La4); fac(a5,1,n+1,La5); fac(a6,1,m,La6); fac(c71,n+2-m+1,n+2,Lc71),fac(c72,1,m,Lc72); chugao(c71,c72,c7,Lc71,Lc72,Lc7); cheng(p2,a4,Lp2,La4,Lp2),cheng(p2,a5,Lp2,La5,Lp2),cheng(p2,a6,Lp2,La6,Lp2),cheng(p2,c7,Lp2,Lc7,Lp2); jian2(p1,p2,ans,Lp1); Lp1=max(Lp1,Lp2); while(!ans[Lp1]&&Lp1>1) Lp1--; print(ans,Lp1); } return 0; } -
-4
方法一:排除法
农夫不相邻 = (不考虑农夫是否相邻) - (农夫相邻)
当然,所有情况的前提是公牛不相邻。
1、不考虑农夫是否相邻:
(1)先把农夫和奶牛看成一样的物体,任意排,有 (n+2)! 种排法
(2)然后把公牛插空,有 A(n+3, m) 种排法。
共 (n+2)!·A(n+3,m) 种
2、农夫相邻:
(1)农夫捆绑成一个物体,和 n 头奶牛任意排,有 2!·(n+1)! 种排法。
(2)公牛插空,有 A(n+2,m) 种排法。
共 2!·(n+1)!·A(n+2,m) 种
答案:(n+2)!·A(n+3,m) - 2!·(n+1)!·A(n+2,m)
方法二:分类讨论
(1)两个农夫之间没有奶牛
此时必然是两个农夫之间有一头公牛,任选一头公牛,把三者捆绑成一个物体,和奶牛任意排,再把剩下的 m-1 头公牛插空排,方案数:
2!·C(m,1)·(n+1)!·A(n+2,m-1)
(2)两个农夫之间有奶牛
先把奶牛排好,然后把农夫插空,再把公牛插空,方案数:
n!·A(n+1,2)·A(n+3,m)
共 2!·C(m,1)·(n+1)!·A(n+2,m-1) + n!·A(n+1,2)·A(n+3,m) 种
- 1
信息
- ID
- 241
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 7
- 标签
- (无)
- 递交数
- 32
- 已通过
- 9
- 上传者