C++ SPOJ 370-一和零(一零)

C++ SPOJ 370-一和零(一零),c++,algorithm,optimization,C++,Algorithm,Optimization,我试图解决: 某些正整数的十进制表示形式仅由1和0组成,并且至少有一位数字1,例如101。如果一个正整数没有这样的属性,可以尝试将它乘以某个正整数,以确定乘积是否具有此属性 我解决这个问题的方法就是做BFS。获取只包含'1'的字符串,然后使用它进行BFS,并在每个步骤中添加'1'和'0'。到目前为止,以字符串形式跟踪数字和余数。当余数为零时,找到该数字 我的问题是:对于测试用例(例如9999或99999),我的代码花费的时间太长。如何改进算法的运行时间 //Shashank Jain /* BF

我试图解决:

某些正整数的十进制表示形式仅由1和0组成,并且至少有一位数字1,例如101。如果一个正整数没有这样的属性,可以尝试将它乘以某个正整数,以确定乘积是否具有此属性

我解决这个问题的方法就是做BFS。获取只包含
'1'
的字符串,然后使用它进行BFS,并在每个步骤中添加
'1'
'0'
。到目前为止,以字符串形式跟踪数字和余数。当余数为零时,找到该数字

我的问题是:对于测试用例(例如9999或99999),我的代码花费的时间太长。如何改进算法的运行时间

//Shashank Jain
/*
BFS
*/
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义LL long long int
使用名称空间std;
LL n;
字符串ans;
void bfs()
{   
字符串str,第一,第二;
str+='1';//数字将始终以'1'开头
如果(n==1)
{
ans=str;
返回;
}
queueq;//字符串(数字)和长整型的一对
//(将剩余部分保留到现在)
pairp;
p=配对(str,1);
q、 推(p);
LL rem、val、temp;
while(q.empty()==0)
{
p=q.front();
q、 pop();
str=p.first;
val=p.second;
如果(val==0)//余数为零表示这是一个数字
{
ans=str;
返回;
}
//将1添加到当前数字
温度=val*10+1;
rem=(温度)%n;
第一个=str+'1';
p=配对(第一对,rem);
q、 推(p);
//将0添加到当前数字
温度=val*10+0;
rem=(温度)%n;
secondone=str+'0';
p=配对(第二对,rem);
q、 推(p);
}
}
int main()
{
int t,i;
scanf(“%d”、&t);
而(t--)
{   
scanf(“%lld”、&n);
bfs();

对于(i=0;i这里有一个提示。请这样思考:

假设你想要的数字是X。 X模N=0

因此,您只需要存储N个状态,即0-N-1。
从1开始。然后做bfs。你需要丢弃与以前具有相同余数的分支。我将把证据留给你。

我刚刚解决了这个问题。我不会发布我的代码片段,但我会给出代码较慢的原因

  • 正如SUKUNRT所说,你需要保持一个数组的大小N,在这里你可以标记当前获得的模数作为访问,这样你就不会再访问它,因为如果你是在一个已经访问过的模数,你不需要考虑直到现在得到的字符串的一部分,因为它只使数字更大(我们需要最小)。,也就是说,一旦你访问了一个模,你说

    x
    ,那么你会发现由0和1组成的最小数,当除以n时,
    x
    作为余数

  • 您总是将这样获得的字符串传递给子级,这不仅增加了内存,还增加了时间。为了避免这种情况,只需再获取两个数组,即大小均为n的
    value[]
    parent[]

    parent[i]
    存储模数的父模数
    i


    <代码>值[i] <代码>存储是对应于模>代码> i>代码>的当前位(0)这正是我正在做的..从队列中弹出丢弃分支并且只有当前考虑的分支运行到!!你确定吗?我不认为你正在保存找到的剩余物.如果1=101(mod n)您正在队列中排队101的子节点。我确实了解第2点。您能再解释一下吗?@shashank我刚才给出了一种方法,以避免将字符串参数传递给您推到队列中的子节点。我可以详细解释,但我认为它不适合comment@Migdal-我重新编码我的解决方案,遵守您的指导原则..比ks它被接受了!!第2点太好了,在实现时很容易被忘记!谢谢!@shahshank很高兴我能帮上忙:)@Christian Ammer-谢谢你的编辑!不客气,将问题描述包含到问题中并有问题地格式化代码总是一个好主意。