hdu 1195 Open the Lock

http://acm.hdu.edu.cn/showproblem.php?pid=1195


這個題廣搜,不過我開始寫的超內存了,估計是廣搜隊列太長了。
然後借鑑了別人的代碼來AC。。但是有一點沒想通,不就是循環範圍改了一下,爲什麼內存差別這麼大。無語。。

一開始超內存代碼:
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>

using namespace std;

struct Node
{
    int nu[4];  //記錄四個位置的密碼值
    int sum;
}p;

int lock[10][10][10][10];  //判重記錄
int pas[4];                //記錄最後的密碼
int a,b,c,d;

void Bfs()
{
    queue<Node> q;
    Node now,next;
    int i;
    int exchange;
    q.push(p);
    while(!q.empty())
    {
        now = q.front();
        q.pop();
        for(i = 0; i < 4; i++)          //判斷密碼是否正確
        {
            if(now.nu[i] != pas[i])
            {
                break;
            }
        }
        if(i == 4)
        {
            printf("%d\n",now.sum);
            break;
        }
        for(i = 0; i < 4; i++)         //每個循環只操作一次
        {
            next = now;
            next.sum++;

            next.nu[i] = now.nu[i]+1;   //第i個數增加一
            if(next.nu[i] > 9)
            {
                next.nu[i] = 1;
            }
            if(lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]] == 0)  //如果沒有經過則入隊
            {
                lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]] = 1;
                q.push(next);
            }

            next.nu[i] = now.nu[i]-1;   //減少一
            if(next.nu[i] < 1)
            {
                next.nu[i] = 9;
            }
            if(lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]] == 0)
            {
                lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]] = 1;
                q.push(next);
            }

            if(i<3)                    //兩個數交換
            {
                next = now;
                nex.sum++;
                exchange = next.nu[i];
                next.nu[i] = next.nu[i+1];
                next.nu[i+1] = exchange;
                q.push(next);
            }
        }
    }
}

int main()
{
    int t,x;
    scanf("%d",&t);
    while(t--)
    {
        memset(lock,0,sizeof(lock));
        memset(pas,0,sizeof(pas));
        scanf("%d",&x);  //輸入當前密碼值
        p.nu[3] = a = x%10;
        x = x/10;
        p.nu[2] = b = x%10;
        x = x/10;
        p.nu[1] = c = x%10;
        x = x/10;
        p.nu[0] = d = x;
        lock[d][c][b][a] = 1;
        p.sum = 0;
        scanf("%d",&x);  //輸入最終密碼
        pas[3] = x%10;
        x = x/10;
        pas[2] = x%10;
        x = x/10;
        pas[1] = x%10;
        x = x/10;
        pas[0] = x;
        Bfs();
    }

    return 0;
}

AC代碼:
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>

using namespace std;

struct Node
{
    int nu[4];  //記錄四個位置的密碼值
    int sum;
}p;

int lock[10][10][10][10];  //判重記錄
int pas[4];                //記錄最後的密碼
int a,b,c,d;

void Bfs()
{
    queue<Node> q;
    Node now,next;
    int i;
    q.push(p);
    while(!q.empty())
    {
        now = q.front();
        q.pop();
        for(i = 0; i < 4; i++)   //判斷密碼是否正確
        {
            if(now.nu[i]!=pas[i])
            {
                break;
            }
        }
        if(i==4)
        {
            printf("%d\n",now.sum);
            break;
        }
        for(i = 0; i < 4; i++)  //每位加一操作
        {
            next = now;
            next.nu[i] = now.nu[i]+1;
            if(next.nu[i]>9)
            {
                next.nu[i] = 1;
            }
            if(lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]]!=1)
            {
                lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]]=1; //標記
                next.sum = now.sum+1;
                q.push(next);
            }
        }
        for(i = 0; i < 4; i++)  //每位減一操作
        {
            next = now;
            next.nu[i] = now.nu[i]-1;
            if(next.nu[i]<1)
            {
                next.nu[i] = 9;
            }
            if(lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]]!=1)
            {
                lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]]=1;
                next.sum = now.sum+1;
                q.push(next);
            }
        }
        for(i = 0; i < 3; i++)  //相鄰的交換
        {
            next = now;
            next.nu[i] = now.nu[i+1];
            next.nu[i+1] = now.nu[i];
            if(lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]]!=1)
            {
                lock[next.nu[0]][next.nu[1]][next.nu[2]][next.nu[3]]=1;
                next.sum = now.sum+1;
                q.push(next);
            }
        }
    }
}

int main()
{
    int t,x;
    scanf("%d",&t);
    while(t--)
    {
        memset(lock,0,sizeof(lock));
        memset(pas,0,sizeof(pas));
        scanf("%d",&x);  //輸入當前密碼值
        p.nu[3] = a = x%10;
        x = x/10;
        p.nu[2] = b = x%10;
        x = x/10;
        p.nu[1] = c = x%10;
        x = x/10;
        p.nu[0] = d = x;
        lock[d][c][b][a] = 1;
        p.sum = 0;
        scanf("%d",&x);  //輸入最終密碼
        pas[3] = x%10;
        x = x/10;
        pas[2] = x%10;
        x = x/10;
        pas[1] = x%10;
        x = x/10;
        pas[0] = x;
        Bfs();
    }

    return 0;
}


發佈了106 篇原創文章 · 獲贊 7 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章