1495. One-two, One-two 2

http://acm.timus.ru/problem.aspx?space=1&num=1495

说是有dp 和 bfs  两种解法 用 dp 不知道其他人怎么做的

我开 int [30][1000000] 直接搜 会超内存 没想到好的方法

所以还是 bfs 吧

结果超时  一直以为Timus 的数据够水 不过 这个题还是超时了

经过不断的优化才过的

思路:

广搜时记录某个 模 是否已经出现 出现了则无需再次入队列 否则入队列 并记录相关信息 

当所有的长度在30以内的可用数全出现了时  马上停止搜索 这一步很关键  大大减少时间

代码及其注释:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>



#define LL long long



using namespace std;



const int N=5000003;

struct node

{

    char L,k;//分别为长度 和 此位的值

    int mod,f;//取模  和 前驱指向

}qt[N];//手写队列

int I,J;

bool had[1000005];//标记这个模是否已出现

int n,nd;

void bfs()

{

    while(I<J)

    {

        char L=qt[I].L;

        int mod=qt[I].mod;

        if(L==30)//已到30 直接停止

        {return ;++I;}

        int mod1=(mod*10+1)%n;//此位用1时的模

        int mod2=(mod*10+2)%n;//此位用2时的模

        if(had[mod1]==false)//如果没有出现 则入队列

        {

            had[mod1]=true;

            qt[J].f=I;qt[J].k=1;qt[J].L=L+1;qt[J].mod=mod1;

            if(mod1==0)//如果搜到答案  停止

            {nd=J;return ;}

            ++J;

        }

        if(had[mod2]==false)

        {

            had[mod2]=true;

            qt[J].f=I;qt[J].k=2;qt[J].L=L+1;qt[J].mod=mod2;

            if(mod2==0)

            {nd=J;return ;}

            ++J;

        }

        ++I;

    }

}

void print(int k)//输出

{

    if(qt[k].L>1)

    print(qt[k].f);

    printf("%d",qt[k].k);

}

int main()

{

    //freopen("data.txt","r",stdin);

    while(scanf("%d",&n)!=EOF)

    {

        if(n==1||n==2)

        {

            printf("%d\n",n);

            continue;

        }

        memset(had,false,sizeof(had));

        I=J=0;

        //初始化

        qt[J].L=1;qt[J].k=1;qt[J].mod=1;++J;

        qt[J].L=1;qt[J].k=2;qt[J].mod=2;++J;

        had[1]=had[2]=true;

        nd=-1;

        bfs();//广搜

        if(nd==-1)

        {printf("Impossible\n");continue;}

        print(nd);

        printf("\n");

    }

    return 0;

}

 

 

你可能感兴趣的:(one)