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;
}
浙公网安备 33010602011771号