A - Find a Number CodeForces - 1070A -记忆化广搜-同余定理

  • A - Find a Number

  •  CodeForces - 1070A 
  • 题意:
  • 思路:与数位dp思想有点相似,数太大无法存储,选择保留其对搜索目标有用的信息,并且记忆化减少无效多余搜索,
  • vis[i][j]两位含义是 当前的 余数为i,各个数位的和为j时是否已经出现过,当各个数位和超过s时也应当continue。
  • 结果记录就用pre数组,注意怎样标记才能控制不断递归到pre恰好为最初的位置
  • #include<bits/stdc++.h>
    using namespace std;
    #define maxn 555
    int d,s,x,y,tx,ty;
    bool vis[maxn][maxn*10];
    vector<int>ans;
    struct node
    {
        int x,y,id;
    } pre[maxn][maxn*10];
    void bfs()
    {
        pre[0][s].id=-1;
        queue<int>q;
        q.push(0);
        q.push(0);
        vis[0][0]=1;
        while(!q.empty())
        {
            x=q.front();
            q.pop();
            y=q.front();
            q.pop();
            for(int i=0; i<10; i++)
            {
                tx=(x*10+i)%d;
                ty=y+i;
                if(vis[tx][ty]||ty>s)continue;
                vis[tx][ty]=1;
                q.push(tx);
                q.push(ty);
                pre[tx][ty].id=i;
                pre[tx][ty].x=x;
                pre[tx][ty].y=y;
            }
        }
        if(pre[0][s].id==-1)
            printf("-1\n");
        else
        {
            x=0,y=s;
            while(x!=0||y!=0)
            {
                ans.push_back(pre[x][y].id);
                tx=x;
                x=pre[x][y].x;
                y=pre[tx][y].y;
            }
            int len=ans.size();
            for(int i=len-1; i>=0; i--)
                printf("%d",ans[i]);
        }
    }
    int main()
    {
        scanf("%d%d",&d,&s);
        bfs();
        return 0;
    }
    

猜你喜欢

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