usaco Prime Cryptarithm 解题报告

本文介绍了一个算法问题,即寻找所有可能的“牛式”乘法竖式组合。给定一组数字,通过枚举不同的组合方式,判断是否能构成有效的乘法竖式,并确保每个数字仅被使用一次且首位不为0。文章提供了详细的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:

下面是一个乘法竖式,如果用我们给定的那n个数字来取代*,可以使式子成立的话,我们就叫这个式子牛式。

        * * *
    x     * *
   ----------
        * * *
      * * *
   ----------
      * * * *

数字只能取代*,当然第一位不能为0,况且给定的数字里不包括0。

注意一下在美国的学校中教的“部分乘积”,第一部分乘积是第二个数的个位和第一个数的积,第二部分乘积是第二个数的十位和第一个数的乘积.

写一个程序找出所有的牛式。

题解:

枚举符合题意的乘数a和b,然后产生product1,product2,和总的product,分别检查是否符合要求,符合就计数器加一

代码:

/*
ID:     lishicao
PROG:   crypt1
LANG:   C++
*/
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std ;

ifstream fin  ( "crypt1.in"  ) ;
ofstream fout ( "crypt1.out" ) ;

int  N  , Count = 0 ;
int  number[10] , num[5] ;

void  dfs( int ) ;
bool  check() ;

int  main()
{
    fin >> N ;
    for( int i = 0 ; i < N ; i ++ )
        fin >> number[i] ;
    dfs( 0 ) ;
    fout << Count << endl ;
    return 0 ;
}

void  dfs( int depth )
{
    if( depth == 5 )
    {
        if( check() ){
            Count ++ ;
        }
        return ;
    }
    for( int i = 0 ; i < N ; i ++ )
    {
        num[depth] = number[i] ;
        dfs( depth + 1 ) ;
    }
}

bool  check()
{
    int  product1 , product2 , product , temp , flag = 0 ;
    product1 = num[4] * ( 100 * num[0] + 10 * num[1] + num[2] ) ;
    product2 = num[3] * ( 100 * num[0] + 10 * num[1] + num[2] ) ;
    product  = product1 + product2 * 10 ;

    if( product1 >= 1000  || product1 < 100  ) return false ;
    if( product2 >= 1000  || product2 < 100  ) return false ;
    if( product  >= 10000 || product  < 1000 ) return false ;


    for( int i = 0 ; i < 3 ; i ++ )
    {
        temp = product1 % 10 ;
        product1 /= 10 ;
        int flag = 0 ;
        for( int j = 0 ; j < N ; j ++ )
            if( temp == number[j] ) flag = 1 ;
        if( flag == 0 ) return false ;

        temp = product2 % 10 ;
        product2 /= 10 ;
        flag = 0 ;
        for( int j = 0 ; j < N ; j ++ )
            if( temp == number[j] ) flag = 1 ;
        if( flag == 0 ) return false ;
    }
    for( int i = 0 ; i < 4 ; i ++ )
    {
        temp = product % 10 ;
        product /= 10 ;
        int flag = 0 ;
        for( int j = 0 ; j < N ; j ++ )
            if( temp == number[j] ) flag = 1 ;
        if( flag == 0 ) return false ;
    }
    return true ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值