SSブログ

AOJ 0503: Cup [AOJ]

JOI予選の問題、全ての年で問4まで解けました.ばんざーい!
Greedyとか漸化式とか言う話がチラチラ聞こえましたが、僕にある武器はDFSとBFSだけだったのです...

訪問状態の管理は3進数で行なっています. 3^15 ≒15000000です.
#include <stdio.h>
#include <string.h>

typedef struct {
    int time;
    int tower[3][15];
    int t[3];
} HANOI;

HANOI queue[50000];
int head, tail;
int pow[30];

void enq(HANOI t)
{
    queue[tail % 50000] = t;
    tail++;
}

void deq(HANOI *t)
{
    *t = queue[head % 50000];
    head++;
}

char v[15000000];

int move(HANOI temp, int from, int to, int pw)
{
    int num;
    int i, j;
    HANOI first;
    if ((temp.t[from] > 0 && temp.t[to] > 0 && temp.tower[from][temp.t[from] - 1] > temp.tower[to][temp.t[to] - 1]) ||temp.t[from] > 0 && temp.t[to] == 0){
        first = temp;
        first.tower[to][temp.t[to]] = first.tower[from][temp.t[from] - 1];
        first.tower[from][temp.t[from] - 1] = 0;
        first.t[from]--;
        first.t[to]++;
        first.time++;
        num = 0;
        for (i = 0; i < 3; i++){
            for (j = 0; j < first.t[i]; j++){
                num += i * pow[first.tower[i][j] - 1];
            }
        }
        if (v[0] == 1 || v[pw] == 1){
            printf("%d\n", first.time);
            return (1);
        }
        if (!v[num]){
            v[num] = 1;
            enq(first);
        }
    }
    return (0);
}

int main(void)
{
    int n, m;
    HANOI start, temp;
    int i, j;
    int pw;
    
    pow[0] = 1;
    for (i = 1; i < 20; i++){
        pow[i] = pow[i - 1] * 3;
    }
    
    while (1){
        scanf("%d%d", &n, &m);
        
        if (n + m == 0){
            break;
        }
        memset(start.tower, 0, sizeof(start.tower));
        for (i = 0; i < 3; i++){
            scanf("%d", &start.t[i]);
            for (j = 0; j < start.t[i]; j++){
                scanf("%d", &start.tower[i][j]);
            }
        }
        
        memset(v, 0, sizeof(v));
        
        start.time = 0;
        head = tail = 0;
        pw = pow[n] - 1;
        enq(start);
        
        while (head != tail){
            deq(&temp);
            
            if (temp.time > m){
                printf("-1\n");
                break;
            }
            
            if (move(temp, 0, 1, pw)){
                break;
            }
            if (move(temp, 1, 0, pw)){
                break;
            }
            if (move(temp, 1, 2, pw)){
                break;
            }
            if (move(temp, 2, 1, pw)){
                break;
            }
        }
    }
    
    return (0);
}

nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

AOJ 0090: Overlaps o..AOJ 0547:Commute rou.. ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。