SPOJ ONEZERO(零和零)

时间:2014-06-03 05:48:32

标签: c++ optimization

我正在尝试通过使用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);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

以另一种方式思考。您有a_i = (10^i) % n,并希望找到b_i = 0..1 sum(a_i * b_i, i) % n = 0。看起来这是一个动态的编程任务。

您有一个数组m,其中m[i][j] = true表示“我可以代表一个k个零和一个k % n == j,我们只需要{{} 1}}数字为“。

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

要显示该号码,您需要从m[i][j] = true回溯m

在发送之前测试所有可能m[somewhere][0] = true的解决方案,因为它们很少(仅20000)。我想你甚至可以预先生成所有解决方案并编写一个数组查找解决方案。