算法竞赛入门10.2计数与概率基础例题代码

来源:互联网 发布:成达工程公司 知乎 编辑:程序博客网 时间:2024/05/19 23:59

10.6 Irrelevant Elements UVA1635


思路:基础组合计数


#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>const int N = 1e5+5;using namespace std;long long C[N][20];int prime[20][2];inline  int judge(int x,int m,int k){    int res = 0;    while(x%m==0){        res+=k;        x/=m;    }return res ;}inline int work(int n,int m,int num){    memset(C,0,sizeof(C));    int ans = 0;    for(int i=1;i<=n;i++)    {        int k=0;        for(int j=0;j<num;j++){            C[i][j]=C[i-1][j]+judge(n-i+1,prime[j][0],1)+judge(i,prime[j][0],-1);            if(C[i][j]>=prime[j][1])k++;        }        if(k==num){            C[i][num]=1;            ans++;        }    }return ans ;}inline int init(int x){    int m = sqrt(x+0.5);    int primenum = 0;    for(int i=2;i<=m;i++){        while(x%i==0){            if(!primenum||prime[primenum-1][0]!=i){                prime[primenum][0]=i;                prime[primenum++][1]=1;            }else {                prime[primenum-1][1]++;            }x/=i;        }    }if(x!=1){        prime[primenum][0]=x;        prime[primenum++][1]=1;    }return primenum ;}int main(){    int n,m;    while(scanf("%d%d",&n,&m)==2)    {        int primenum=init(m);        int ans = work(n-1,m,primenum);        printf("%d\n",ans);        if(ans==0){            printf("\n");            continue;        }        for(int i=0;i<n;i++){//printf("%lld ",C[i]);            if(C[i][primenum]>0)printf("%d%c",i+1,(--ans)?' ':'\n');        }    }    return 0;}


10.7 Send a Table UVA10820


思路:1~n 的欧拉值 复杂度O(nloglogn)

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int N = 50000+5;int phi[N];inline void phi_table (int n){    memset(phi,0,sizeof(phi));    phi[1]=1;    for(int i=2;i<=n;i++) if(!phi[i]){        for(int j=i;j<=n;j+=i){            if(!phi[j])phi[j]=j;            phi[j] = phi[j]/i*(i-1);        }    }}int main(){    int n;    while(scanf("%d",&n)==1&&n)    {        phi_table(n);        long long ans = 1;        for(int i=2;i<=n;i++)            ans += phi[i]*2;        printf("%lld\n",ans);    }}


10.9 Headshot UVA1636


思路:条件概率

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;char str[105];int main(){    while(gets(str)!=NULL)    {        int n=strlen(str);        int num1=0,num2=0;        for(int i=0;i<n;i++)        {            if(i!=n-1&&str[i]=='0'&&str[i+1]=='1')                num1++;            if(i==n-1&&str[i]=='0'&&str[0]=='1')                num1++;            if(str[i]=='1')                num2++;        }        int  p1=num1*(n-1),p2=(n-num2)*num2;        if(p1<p2)            printf("SHOOT\n");        else if(p1>p2)            printf("ROTATE\n");        else            printf("EQUAL\n");    }    return 0;}


10.10 Cows and Cars UVA10491


思路:全概率公式

#include<cstdio>#include<algorithm>using namespace std;int main(){    int a,b,c;    while(scanf("%d%d%d",&a,&b,&c)==3)    {        double ans=(b*b-b+a*b)/((a+b)*(a+b-c-1));        printf("%.2f\n",ans);    }}


10.11 Probability|Given UVA11181


思路:全概率+条件概率

#include<cstdio>#include<vector>#include<cstring>#include<algorithm>using namespace std;double e[1100000];int n,m;double p[25];double ans[25];vector<int>A[21];inline void oper(int x){    int cur = 0,y=x;    while(x){        cur += x%2;        x>>=1;    }A[cur].push_back(y);}inline void init(){    for(int x=1;x<1100000;x++){        oper(x);    }}inline double work(int x){    double res = 1;    for(int i=0,tem=1;i<n;tem<<=1,i++){        if(x&tem) res*=p[i];        else res*=(1-p[i]);    }for(int i=0,tem=1;i<n;tem<<=1,i++){        if(x&tem) ans[i]+=res;    }return res;}int main(){    int t=0;init();    while(scanf("%d%d",&n,&m)==2)    {        if(!n&&!m)break;        memset(ans,0,sizeof(ans));        for(int i=0;i<n;i++)        {            scanf("%lf",&p[i]);        }double sum = 0;        printf("Case %d:\n",++t);        if(m==0){            for(int i=0;i<n;i++)                printf("0.000000\n");            continue;        }        for(int i=0;i<A[m].size()&&A[m][i]<(1<<n);i++)        {            //printf("x = %d\n",A[m][i]);            sum += work(A[m][i]);        }        for(int i=0;i<n;i++)            printf("%.6f\n",ans[i]/sum);    }}


10.12 Double Patience UVA1637


思路:状压记忆化搜索  九位5进制表示牌堆的状态进行记忆化搜索或者用九维数组进行dp都行


#include<cstdio>#include<cstring>#include<vector>#include<algorithm>#include<cmath>const int Max = 1953124;using namespace std;bool vis[Max+5];char card[10][5][3];double  step[Max+5];inline void oper(int *now,int x){    for(int i=0;i<9;i++){        now[i] = x%5;        x/=5;    }}inline int get_id(int *now,int a,int b){    int res = 0 ;    for(int i=8;i>=0;i--)    {        res = res*5 + now[i];        if(i==a||i==b)res--;    }    return res ;}inline double dfs(int x){//printf("x=%d\n",x);//if(x==0)system("pause");    if(vis[x])return step[x];    vis[x] = true;    int now[10];    oper(now,x);    int cur = 0;    for(int i=0;i<9;i++)    {        for(int j=i+1;j<9;j++)        {            if( now[i] && now[j] && card[i][now[i]][0] == card[j][now[j]][0] )            {                int id = get_id(now,i,j);                step[x] += dfs(id);                cur++;                //system("pause");            }        }    }    if( cur ) step[x] /= cur;    return step[x];}int main(){    while(scanf("%s %s %s %s",card[0][1],card[0][2],card[0][3],card[0][4]) == 4 )    {        for(int i=1;i<9;i++)            for(int j=1;j<=4;j++)                scanf("%s",card[i][j]);        memset(step,0,sizeof(step));        memset(vis,0,sizeof(vis));        step[0]=1.0;vis[0]=true;        double ans = dfs(Max);        printf("%.6f\n",ans);    }    return 0;}



0 0
原创粉丝点击