zoukankan      html  css  js  c++  java
  • USACO 1.3.4 Prime Cryptarithm

    //译题
    //★Prime Cryptarithm 牛式
    下面是一个乘法竖式,如果用我们给定的那几个数字来取代*,可以使式子成立的话,我们就叫这
    个式子牛式.
       * * *
    x    * *
       -------
       * * *
    * * *
    -------
    * * * *
    数字只能取代*,当然第一位不能为0.
    写一个程序找出所有的牛式.
    PROGRAM NAME: crypt1
    INPUT FORMAT
    Line 1: 数字的个数.
    Line 2: N 个用空格分开的数字(每个数字都∈{1,2,3,4,5,6,7,8,9}) .
    SAMPLE INPUT (file crypt1.in)
    5
    2 3 4 6 8
    OUTPUT FORMAT
    共一行,一个数字.表示牛式的总数.下面是样例的那个牛式.
       2 2 2
    x    2 2
       ------
       4 4 4
    4 4 4
    ---------
    4 8 8 4
    SAMPLE OUTPUT (file crypt1.out)
    1
    /*
    这道题目也用枚举,由于数据比较小,所以可以全部遍历一遍,
    再考虑0不能使用,
    所以从111 开始到 999 ,11开始到99;
    我写的代码有完全模拟竖式的味道,
    用了5个数组分别存放牛式的每一行 
    
        2 2 2       t1[]
    x      2 2        t2[]
       ------
        4 4 4        t3[]
      4 4 4            t4[]
    ---------
      4 8 8 4        comp[]
    
    实际上还有很多地方可以优化 
    S1 S4 S5
    × S2 S3
    约束条件只有3个:第3、4行是3位数,第5行是4位数。按S1到S5的顺序搜索。
    如果S1×S2>10或者S1×S3>10,则3、4行肯定不是3位数,剪枝。
    即S1*S2+S4*S2/10>=10 || S1*S3+S4*S3/10>=10 剪枝。
    补充:从高位到低位,从小到大填数据,如果发现乘积超过999就剪枝。
    */
    
    ---------------------------------------------------------------------------------------------------
    参考代码1(代码中附有解释)
    ---------------------------------------------------------------------------------------------------
    
    /*
    ID: china_l5
    LANG:C
    TASK: crypt1
    */
    #include<stdio.h>
    int judge(int n, int *m, int s)        //用来判断数 n 是否是数组 m 中的元素 
    {                                     
        int i,*p = m ,flag;
        for(i=0;i<s;i++)
            {
                if(n==*p) {flag = 1; break;}
                else flag = 0; 
                p++;
            }
        return flag;
    }
    char x[5], y[5];
    int t1[5], t2[5],t3[5], t4[5], num[10], sum[5],comp[5];
    // t1 竖式的第一行 t2 第二行 t3 第三行 t4 第四行 
    // num数组存放 可以用到的数 
    //comp 用于比较 
    int main()
    {
        freopen("crypt1.in","r",stdin);
        freopen("crypt1.out","w",stdout);
        int N,i,j,k,p,q,tmp,flag=0,count=0;
        
        scanf("%d",&N);        //读入N 
        for(i=0;i<N;i++)
            scanf("%d",&num[i]);    //读入可以用到的数,存在num中 
        for(i=111;i<=999;i++)        //遍历111 到 999 因为不能用 0 ,且牛式的第一行为一个三位数 
        {
            t1[3] = i/100; t1[2] = i%100/10; t1[1] = i%100%10;
            if(!judge(t1[3],num,N))        continue;    //如果第一行中有不属于num数组中的数存在的话,continue 
            if(!judge(t1[2],num,N))        continue;
            if(!judge(t1[1],num,N))     continue;
            
                for(j=11;j<=99;j++)        //遍历 11到 99 理由同上 
                {
                    flag=2;    
                    t2[2] = j/10; t2[1] = j%10;
                    if(!judge(t2[2],num,N))    continue;    //如果第二行中有不属于num数组中提供的数的话,continue 
                    if(judge(t2[1],num,N))
                    {
                        for(q=1,tmp=0;q<=3;q++)            //算出第三行的每个数 
                            {
                                t3[q] = ( t1[q] * t2[1] + tmp)%10 ;    
                                tmp   =    ( t1[q] * t2[1] + tmp)/10;
                            }
                        if (tmp>0) continue;            //如果存在进位,continue,自己想想为什么 
                        for(q=1,tmp=0;q<=3;q++)            //算出第四行的每个数 
                            {
                                t4[q+1] = ( t1[q] * t2[2] + tmp)%10 ;
                                tmp   =    ( t1[q] * t2[2] + tmp)/10;
                            }                            //如果有进位的话,同上 
                        if (tmp>0) continue;
                        if(!judge(t3[1],num,N))        continue;        //判断同上 
                        if(!judge(t3[2],num,N))        continue;
                        if(!judge(t3[3],num,N))        continue;
                        if(!judge(t4[2],num,N))        continue;
                        if(!judge(t4[3],num,N))        continue;
                        if(!judge(t4[4],num,N))        continue;
                        
                        comp[1] = t3[1];
                        if(!judge(comp[1],num,N))    continue; 
                        comp[2] = (t3[2]+t4[2])%10;      tmp=(t3[2]+t4[2])/10;
                        if(!judge(comp[2],num,N))    continue; 
                        comp[3]    = (t3[3]+t4[3]+tmp)%10;  tmp=(t3[3]+t4[3]+tmp)/10;
                        if(!judge(comp[3],num,N))    continue; 
                        comp[4] = t4[4]+tmp;
                        if(!judge(comp[4],num,N))    continue; 
                        if(flag==2) count++;            //count计数        
                     }        
                }    
        }
        printf("%d
    ",count);    //输出count 
        return 0;
    }
     
    ---------------------------------------------------------------------------------------------------
    参考代码2(这种算法的话,时间上反而多了点)
    ---------------------------------------------------------------------------------------------------
    
    #include<stdio.h>
    #include<string.h>
    int x,y,abc,de,f,g,h,count;
    char s[20],buf[100];
    int main()
    {
        freopen("crypt1.in", "r", stdin);
        freopen("crypt1.out", "w", stdout);
        int i,ok;
        scanf("%d
    ", &i);
        fgets( s, 2*i, stdin);
        for(abc = 111; abc < 1000; abc++)
           for(de = 11; de < 100; de++) {
               f = abc * (de/10);
               g = abc * (de%10);
               h =  abc * de;
               ok = 1;
               if( (f / 1000 > 0) || (g / 1000 > 0) || (h / 10000 > 0) )continue;
               sprintf(buf,"%d%d%d%d%d",abc,de,f,g,h);
               for(i = 0; i < strlen(buf); i++)
                  if(strchr(s, buf[i]) == NULL) {ok = 0; break;}
               if(ok) count++;
           }
        printf("%d
    ",count);
        return 0;
    }
  • 相关阅读:
    20145224&20145238 《信息安全系统设计基础》 第四次实验
    20145224&20145238 《信息安全系统设计基础》 第三次实验
    《信息安全系统设计基础》 第十一周学习总结
    20145211《信息安全系统设计基础》实验二 固件设计
    20145211《信息安全系统设计基础》实验五 网络通信
    20145211《信息安全系统设计基础》课程总结
    20145211 《信息安全系统设计基础》第十四周学习总结
    20145211 《信息安全系统设计基础》第十三周学习总结
    20145211《信息安全系统设计基础》第十二周学习总结
    GDB调试汇编堆栈过程分析
  • 原文地址:https://www.cnblogs.com/Lee-geeker/p/3231588.html
Copyright © 2011-2022 走看看