【问题标题】:SPOJ ONEZERO (ones and zeros)SPOJ ONEZERO(一和零)
【发布时间】:2015-01-22 07:04:48
【问题描述】:

我正在尝试通过使用 BFS 并存储剩余部分并更新它来解决问题 here。但是,我这样做时会得到 TLE,我该如何消除它?

int t,n,i,j,z,y;

string l,m;
scanf("%d",&t);
while(t--)
{
    scanf("%d",&n);
    pair<string,int>b;
    queue<pair<string,int> >a;
    b=make_pair("1",1);
    a.push(b);
    bool r[20001]={0};
    while(!a.empty())
    {
        b=a.front();
        a.pop();
       // cout<<b.first<<endl;
        if(b.second%n==0)
        {
            printf("%s\n",b.first.c_str());
            break;
        }
        m=b.first;
        y=b.second;
        z=(y*10)%n;
        if(r[z]==0)
        {    r[z]=1;
             l=m+'0';
        b=make_pair(l,z);
        a.push(b);
        }

        z=(y*10+1)%n;
        if(r[z]==0)
        {    r[z]=1;
             l=m+'1';
        b=make_pair(l,z);
        a.push(b);
        }
    }
}

【问题讨论】:

  • 您能解释一下您的代码是如何工作的吗?
  • 问题是找出最小的数只包含 0 和 1 能被 n 整除。我正在使用 bfs 并有一个队列,该队列由该数字作为字符串和一对余数组成。首先我插入 1,然后如果余数为 0,则将 0 和 1 添加到队列中,然后我打印答案并打破循环
  • 你需要发明比 BFS 更智能的东西。这就是重点。这些问题的设计使得 BFS 将 TLE。
  • @n.m.我不会那么肯定。它可以是图搜索优化的任务。

标签: c++ optimization


【解决方案1】:

换个角度想。你有a_i = (10^i) % n,你想找到这样的b_i = 0..1sum(a_i * b_i, i) % n = 0。看起来这是一个动态编程任务。

您有一个数组m,其中m[i][j] = true 表示“我可以表示一个由0 和1 组成的数字k,例如k % n == j,我们需要的数字不超过i”。

在您的 DP 公式中,当 m[i][j] = true 时,您有 m[i+1][j] = m[i+1][(j + 10^i) % n] = true

要显示该号码,您需要从 m[somewhere][0] = true 回溯到您的 m

在发送之前为所有可能的n 测试您的解决方案,因为它们很少(只有 20000 个)。我认为您甚至可以预先生成所有解决方案并编写一个数组查找解决方案。

【讨论】:

    猜你喜欢
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-10
    • 2016-11-11
    相关资源
    最近更新 更多