POJ1426 - BFS

   题目的意思是写出一个只由0,1组成的数...这个数位做给数的整数倍...

   开始我是依次生成每个0,1数...再check是不是倍数...然后一跑..效率太低了...就说打表...打了1个小时都出不来...后来一看只打到了16..200个估计一天是搞不定了...

   后来想到我可以BFS...从第位向高位的来确定乘数...因为乘数的个位数确定了..那么积的个位就确定了..如果乘数的个位和十位都确定了...那么积的十位和个位就都确定了...依次类推...保证每次进入队列的数除后面几位都只由0,1组成....直到所有数都是由0,1组成就找到了解..这题是Special Judge...找到了就输出就行了...

   在BFS的时候...我循环0~9...都能出解...但交上去居然超时....实在我是离线打表..打表时间目测一闪而过...后面就是来一个出一个....这都能TLE...好吧....干脆就把循环开成1~9试一试....结果发现就一个数的解出不来...n=36...最小的乘积应该是11111111100...如果循环开成1~9..那么再下一个就爆了long long了..无奈..就这个数不行...我就萎缩的直接输出了这个解了....


Program : 

#include<iostream>
#include<queue>
using namespace std; 
struct pp
{
    int k;
    long long data,PowOfTen;      
}h,p;
queue<pp> myqueue; 
int i,n;
bool ok(pp k)
{
    long long p=k.data;
    if (!p) return false;
    while (p>0)
    {
       if (p%10!=1 && p%10!=0) return false;
       p/=10;     
    }
    return true;    
}
long long ans[201];
int main()
{ 
    for (n=1;n<=200;n++)
    {
        if (!n) break;         
        while (!myqueue.empty()) myqueue.pop();      
        p.data=0; p.k=0; p.PowOfTen=1; 
        myqueue.push(p);        
        while (!myqueue.empty()) 
        {
            h=myqueue.front(); 
            myqueue.pop(); 
            for (i=1;i<=9;i++)
            if ((i*n%10+h.k)%10==1 || (i*n%10+h.k)%10==0)
            {
                p=h;
                p.data+=h.PowOfTen*i*n;
                p.PowOfTen*=10;
                p.k=(int)(p.data/p.PowOfTen);             
                if (ok(p)) goto A;  
                myqueue.push(p);             
            }
        }
        A:  ans[n]=p.data;
    }
    ans[36]=11111111100ll;
    while (~scanf("%d",&n)) 
    {
         if (!n) break;
         printf("%I64d\n",ans[n]);      
    }
    return 0;   
}


你可能感兴趣的:(POJ1426 - BFS)