01组成的N的倍数 -同余定理

  • ①Bfs过程中,在结构体中维护一个字符串a,表示是答案,如果我们每一次都对a整个大数取模操作的话,会增加大量的操作,因为我们每一次都是在字符串末尾加上一位,而且大数取模的过程也是从第一位开始一直向后扫着模的,所以我们这里维护一个变量num,表示当前这个答案a对n的模是多少,那么对应将下一个字符加在最后一位的时候,我们对应维护num=(num*10+0/1)%n即可。
  • ②最关键的剪枝,根据同余定理我们知道,如果对应%n的一个数出现过了,那么接下来我们再继续有一个字符串a%n==这个出现过的数是多余的处理,所以我们对应建立一个vis【i】表示%n==i的字符串我们是否出现过即可。【好棒啊这个剪枝】
  • #include<bits/stdc++.h>
    using namespace std;
    #define maxn 2000006
    #define ll long long
    bool vis[maxn];
    ll n;
    struct node
    {
        string str;
        ll m;
    } top,temp;
    void bfs()
    {
        queue<node>q;
        temp.str="10";
        temp.m=10%n;
        vis[temp.m]=1;
        q.push(temp);
        temp.str="11";
        temp.m=11%n;
        vis[temp.m]=1;
        q.push(temp);
        while(!q.empty())
        {
            top=q.front();
            q.pop();
            if(top.m==0)
            {
                cout<<top.str<<endl;
                return ;
            }
            temp.str=top.str+'0';
            temp.m=top.m*10+0;
            temp.m%=n;
            if(!vis[temp.m])
            {
                vis[temp.m]=1;
                q.push(temp);
            }
            temp.str=top.str+'1';
            temp.m=top.m*10+1;
            temp.m%=n;
            if(!vis[temp.m])
            {
                vis[temp.m]=1;
                q.push(temp);
            }
        }
    }
    int main()
    {
        while(cin>>n)
        {
            memset(vis,0,sizeof(vis));
            if(n==1)
                cout<<1<<endl;
            bfs();
        }
        return 0;
    }
  •  

猜你喜欢

转载自blog.csdn.net/BePosit/article/details/82711920