从1开始后面补0,或1,不断搜下去,直到搜到结果为止。相当于模拟除法的过程。
DFS,BFS均可,由于我用DFS,防止出现极端情况(比如10000000000000000000000000),于是就让深搜方向随机选择,就可防止这种情况出现。不过,不知为什么G++提交老runtime error。
剪枝的方法(如果随机DFS,剪枝效率不明显):模拟除法过程,如果余数出现相同就不再搜下去了。
#include <iostream>
#include <cstdio>
#include <queue>
#include <ctime>
#include <cstdlib>
#include <cstring>
using namespace std;
int n;
bool flag;//如果搜到成功,flag为true
int AnsLen;
char ans[110];//最后结果
bool visit[250];//剪枝标记
void dfs(int remainder,int num,char res[],int depth)//remainder为余数,depth为搜索深度
{
if(depth >101)
{
return;
}
if(flag == true)
{
return;
}
depth++;
int Cremainder;
Cremainder =(remainder * 10) % num;
if(Cremainder == 0)//余数为0,则索到答案
{
res[depth]='0';
res[depth + 1]='\0';
strcpy(ans,res);
// printf("%s\n",res);
AnsLen = strlen(res);
flag = true;
return;
}
//////////////////
Cremainder =(remainder * 10 + 1) % num;
if(Cremainder == 0)
{
res[depth]='1';
res[depth + 1]='\0';
strcpy(ans,res);
AnsLen =strlen(res);
// printf("%s\n",res);
flag = true;
return;
}
///////////////////////////
int cnum;
cnum =rand() % 2;//随机选择搜索方向
if(cnum == 1)
{
Cremainder =(remainder * 10) % num;
res[depth]='0';
res[depth + 1]='\0';
dfs(Cremainder,num,res,depth);
///////////////
Cremainder =(remainder * 10 + 1) % num;
res[depth]='1';
res[depth + 1]='\0';
if(visit[Cremainder] == false)
{
visit[Cremainder] = true;
dfs(Cremainder,num,res,depth);
}
}
else
{
Cremainder =(remainder * 10 + 1) % num;
res[depth]='1';
res[depth + 1]='\0';
dfs(Cremainder,num,res,depth);
/////////////
Cremainder =(remainder * 10) % num;
res[depth]='0';
res[depth + 1]='\0';
if(visit[Cremainder] == false)
{
visit[Cremainder] = true;
dfs(Cremainder,num,res,depth);
}
}
}
int main()
{
int num;
srand(time(NULL));
while(scanf("%d",&num) != EOF)
{
if(num == 0)
{
break;
}
int remainder;
remainder = 1;
char res[110];
while(1)
{
res[0] = '1';
res[1] = '\0';
flag = false;
memset(visit,0,sizeof(visit));
dfs(remainder,num,res,0);
if(AnsLen <= 100 && flag == true)
{
printf("%s\n",ans);
break;
}
}
}
return 0;
}
1391

被折叠的 条评论
为什么被折叠?



