1. 程式人生 > >A - Find a Number CodeForces - 1070A -記憶化廣搜-同餘定理

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;
    }