1. 程式人生 > >T51658 【wsy】簽到題

T51658 【wsy】簽到題

scan printf 狀態 pri 慢慢 bre 為什麽 int 得到

luogu模擬賽T1,爆零的我實在是太菜了!

這道題很容易想到bfs的思路,但是如何優雅地擴展狀態?

我原本的做法是記錄每一位,然後慢慢去擴展狀態,結果爆零了。不知道為什麽。

std的做法是直接通過運算來得到新的數字。通過許多比較不顯然的除法和取膜就可以完成節點的擴展。

哎,我還是太菜了!

代碼:

#include<cstdio>
#include<cstring>
#include<queue>
const int maxn = 1000005;
const int INF = 0x3f3f3f3f;
const int pwd[] = {1, 10, 100, 1000, 10000, 100000};
bool ok[maxn];
int dist[maxn];
int main()
{
    for(int i = 0; i <= 1000; i++) ok[i * i] = true;
    int T; scanf("%d", &T);
    while(T--)
    {
        int x; scanf("%d", &x);
        if(ok[x])
        {
            printf("0\n");
            continue;
        }
        memset(dist, 0x3f, sizeof dist);
        dist[x] = 0;
        std::queue<int> q;
        q.push(x);
        while(!q.empty())
        {
            int u = q.front(); q.pop();
            if(ok[u])
            {
                printf("%d\n", dist[u]);
                break;
            }
            for(int i = 0; i <= 5; i++)
            {
                if(pwd[i] > u) break;
                int pos = u / pwd[i] % 10;
                int v = u - pos * pwd[i];
                for(int j = 0; j <= 9; j++)
                {
                    int newu = v + j * pwd[i];
                    if(dist[newu] == INF && newu)
                    {
                        dist[newu] = dist[u] + 1;
                        q.push(newu);
                    }
                }
                int newu = u % pwd[i] + (u / pwd[i + 1]) * pwd[i];
                if(dist[newu] == INF && newu)
                {
                    dist[newu] = dist[u] + 1;
                    q.push(newu);
                }
            }
        }
    }
    return 0;
}

T51658 【wsy】簽到題