POJ 1465 Multiple (广搜,哈希判重)

本文介绍了一种利用宽度优先搜索(BFS)结合Hash表的方法,解决寻找由特定数字组成的最小倍数的问题。该算法通过剪枝优化搜索过程,避免重复计算,并通过字符串处理实现了对大数的支持。

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

题意:给定一个数n,以及几个数字,求仅包含给定数字的n的最小倍数.

分析:宽搜+hash判重,判重时用到这个剪枝剪枝
形如
A=MX+R
B=NX+R
假设A,B对于X的余数相同
那么
(10*A+d[i])%x
(10*B+d[i])%x
的意义是一样的,所以只有当余数没出现过的情况下才加入到搜索的队列中来但在搜索过程中有可能出现大数,具体怎么处理的,祥看我的代码。

//428K  672MS
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<cstring>
#include<set>
#include<string>
#include<cmath>
#include<algorithm>
#define N 5005
#define DEBUG puts("Hello world!") ;

using namespace std ;

queue<string>str ;  //防止出现大数
int hash[N] ;
string digit[15] ;



int
Get_Mod ( string s , int n )    //直接通过字符串形式求得其为整数形式的余数
{
    int mod ;
    mod = 0 ;
    for ( int i = 0 ; i < s.size() ; i ++ )
    {
        mod = ( mod * 10 + s[i] -'0' ) % n ;
    }
    return mod ;
}

void
Init_Hash ( )
{
    for( int i = 0 ; i <= N ; i ++ )
    {
        hash[i] = false ;
    }
}


bool
Assgin_The_Queue ( int n , int count  ) //为队列开始赋值(个数为count的个数)
{
    int flag ;
    flag = 0 ;
    for ( int i = 1 ; i <= count ; i ++ )
    {
        if ( "0" != digit[i])
        {
            int mod ;
            mod = Get_Mod ( digit[i] , n ) ;
            if ( !hash[mod] )
            {
                hash[mod] = true ;
                if ( 0 == mod )
                {
                    cout << digit[i] << endl ;
                    flag = 1 ;
                    break ;
                }
                str.push ( digit[i] ) ;
            }
        }
    }
    return 1 == flag ? true : false ;
}

void
BFS ( int  n , int count )
{

    int flag ;      //标记是否有Mutiple
    flag = 0 ;
    while ( !str.empty( ) )
    {
        string data ;
        data = str.front( ) ;
        str.pop ( ) ;
        for ( int i = 1 ; i <= count ; i ++ )
        {
            string new_data ;
            new_data = data + digit[i] ;
            int mod ;
            mod = Get_Mod ( new_data , n ) ;
            if ( !hash[mod] )
            {
                hash[mod] = true ;
                if ( 0 == mod )
                {
                    cout << new_data << endl ;
                    flag = 1 ;
                    break ;
                }
                str.push( new_data ) ;
            }
        }
        if ( flag )
        {
            break ;
        }
    }
    if ( !flag )
    {
        printf ("0\n") ;
    }
    return ;
}

void
Empty_The_Queue ( )
{
    while ( !str.empty( ) )
    {
        str.pop ( ) ;
    }
}


int
main ( )
{
    int n ;
    while ( EOF != scanf ("%d" , & n ) )
    {
        int count ;
        scanf ("%d" , & count ) ;
        for ( int i = 1 ; i <= count ; i ++ )
        {
            cin >> digit[i] ;
        }
        if ( 0 == n )
        {
            printf ("%d\n" , 0 ) ;
            continue ;
        }
        sort ( digit+ 1, digit + 1 + count ) ;
        Init_Hash ( ) ;
        if ( Assgin_The_Queue ( n , count ) )
        {
            continue ;
        }
        BFS ( n ,  count ) ;
        Empty_The_Queue ( ) ;
    }
    return 0 ;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值