【问题标题】:SPOJ 370 - Ones and zeros (ONEZERO)SPOJ 370 - 1 和 0 (ONEZERO)
【发布时间】:2013-06-01 11:45:00
【问题描述】:

我正在尝试解决SPOJ problem "Ones and zeros"

某些正整数的十进制表示仅由 1 和 0 组成,并且至少有一位数字 1,例如101. 如果一个正整数不具有这样的性质,可以尝试将其与某个正整数相乘,以确定乘积是否具有这种性质。

我解决这个问题的方法只是做 BFS。获取仅包含 '1' 的字符串,然后对其进行 BFS,并在每一步添加 '1''0'。一直以字符串形式跟踪数字和余数。当余数为零时,该数被找到。

我的问题是:我的代码用于测试用例的时间太长,例如9999 或 99999。如何提高算法的运行时间?

// Shashank Jain
/*
     BFS
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <climits>
#include <string>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#define LL long long int
using namespace std;
LL n;
string ans;

void bfs()
{   
  string str,first,second;
  str+='1'; // number will start with '1' always
  if(n==1)
  {
    ans=str;
    return;
  }
  queue<pair<string,LL> >q; // pair of STRING(number) and long long int
                            // (to hold remainder till now)
  pair<string,LL>p;
  p=make_pair(str,1);
  q.push(p);
  LL rem,val,temp;
  while(q.empty()==0)
  {
    p=q.front();
    q.pop();
    str=p.first;
    val=p.second;   
    if(val==0)  // remainder is zero means this is number 
    {
      ans=str;
      return ;
    }
    // adding 1 to present number       
    temp=val*10+1; 
    rem=(temp)%n;
    firstone=str+'1';
    p=make_pair(firstone,rem);
    q.push(p);
    // adding 0 to present number       
    temp=val*10+0;
    rem=(temp)%n;
    secondone=str+'0';
    p=make_pair(secondone,rem); 
    q.push(p);  
  }
}

int main()
{
  int t,i;
  scanf("%d",&t);
  while(t--)
  {   
    scanf("%lld",&n);       
    bfs();
    for(i=0;i<ans.size();i++)
    {
      printf("%c",ans[i]);        
    }
    printf("\n");
  }
  return 0;
}

【问题讨论】:

  • @Christian Ammer - 感谢您的编辑!
  • 不客气,将问题描述包含在问题中并以探测方式格式化代码总是一个好主意。

标签: c++ algorithm optimization


【解决方案1】:

我刚刚解决了这个问题。我不会发布我的 sn-p,但我会指出为什么你的代码比较慢

    1234563不需要考虑到目前为止获得的字符串部分,因为它只会使数字更大(我们需要最小),即这意味着一旦您访问一个模数,您说x,那么您会找到由 0 和 1 组成的最小数字当除以 n 时,得到 x 作为余数。
  1. 你总是将这样获得的字符串传递给孩子,这不仅增加了内存,也增加了时间。为避免这种情况,只需再使用两个数组,例如 value[]parent[],大小均为 n。

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

    value[i] 存储与模数i (0

    最后你可以回溯到模数=0的整数。

    同样在进行更改后,您的代码将给出 WA,因为您必须首先推送通过在末尾附加“0”获得的孩子,然后通过在末尾附加“1”获得的孩子。 (你可以自己证明)。

【讨论】:

  • 我确实了解第 2 点。您能解释一下吗?
  • @shashank 我只是提供了一种方法来避免将字符串参数传递给您推入队列的子节点我可以详细解释,但我认为它不适合评论
  • @Migdal-我重新编码我的解决方案以保持您的指导方针..谢谢它被接受了!第2点太好了,实施时容易忘记!谢谢!
  • @shahshank 很高兴我能帮上忙 :)
【解决方案2】:

这里有一个提示。这样想:

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

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

【讨论】:

  • 这正是我正在做的......从队列中弹出丢弃分支,只有当前考虑分支运行到!
  • 你确定。我不认为您将找到的剩余部分保存在任何地方。
  • 如果 1 == 101 (mod N) 你正在排队 101 的孩子。
猜你喜欢
  • 1970-01-01
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多