【CQ】2016联合考试 电路图A

来源:互联网 发布:中俄大桥 知乎 编辑:程序博客网 时间:2024/05/21 07:52

这里写图片描述

不想吐槽清华某人出的题了,但不看第三题那个987行的标程,前两题还能做,此题分析在task函数中
#include<cstdio>#include<cstdlib>#include<iostream>#include<vector>#include<cmath>#include<cstring>#define maxn 2005#define mod 1000000007using namespace std;typedef long long lint;int n,m,sz_p;lint ans,ans2,t1,t2;bool is_prime[100000005];vector<int>p,e;void prime_task(lint x){    memset(is_prime,1,sizeof(is_prime));    for(int i=2;i*i<=x;i++) if(is_prime[i])    for(int j=i;j*i<=x;j++) is_prime[i*j]=0;    for(int i=2;i<=x;i++) if(is_prime[i])    {        p.push_back(i);        e.push_back(0);    }    sz_p=p.size();}void break_into(int x,int d){    if(x==1) return;    for(int i=0;p[i]<=x&&i<sz_p;i++)    {        lint t=0,tt=p[i];        while(x>=tt)        {            t+=x/tt;            tt*=p[i];        }        e[i]+=d*t;    }}lint C(int a,int b){    for(int i=0;i<sz_p;i++) e[i]=0;    break_into(a,1);    break_into(a-b,-1);    break_into(b,-1);    lint t=1;    for(int i=0;i<sz_p;i++)    for(int j=1;j<=e[i];j++) t=(t*p[i])%mod;    return t;}void task1(){    //分析可知n个元件(n>=4),需要转向n次,其中需要逆时针转m=(n-4)/2次    //如n=6时,m=1,rrrlrr为一种方案     //在n次转向中选m个空位填l的方案数就是第一问的答案    ans=C(n,m);    cout<<ans<<endl;}void task2(){    //仍然是组合数的算法    //对于n-m次R和m次的L    //手动画出的美观电路图是一个有直边有阶梯的图形,一定不能有连续的两次L               __________              _|        _|      -> 直边 |        _|      <-阶梯             |      _|               |_____|         这个图极为美观     t1=C(n-m-1,m);  //电源在凸多边形的直边上:存在r------r(以r和r结尾),中间有n-m-1个空,填m个l     t2=C(n-m-1,m-1);//电源在阶梯上,则存在l---r或r---l,中间有n-m-1个空,填m-1个l的方案数     t2=(t2+t2)%mod; //l和r分别作为头和尾是两种情况     ans2=(t1+t2)%mod;    cout<<ans2<<endl;}int main(){    //freopen("A.in","r",stdin);    //freopen("A.out","w",stdout);     scanf("%d",&n);    m=(n-4)/2;    prime_task(2*n);    task1();    task2();     return 0;}
0 0
原创粉丝点击