Sicily 1053. Peg Game

1053. Peg Game

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB , Special Judge

Description

You are given a 7-by-7 board of holes. Some holes are filled with pegs, and some are not. You may jump a peg over an adjacent peg, as long as the hole the jumping peg lands in is unoccupied. The jumped peg is removed. Your goal is to leave the board with only one peg in it, and the peg must end up in the specified location.

The board is specified as a 7-by-7 array of characters, with the following meanings:

x: this hole may never be occupied by a peg
e: this hole is initially empty
o: this hole is initially occupied by a peg
E: this hole is initially empty, and the last peg should end here
O: this hole is initially occupied, and the last peg should end here

For example, consider the following board:

x x e e e x x
x x o e e x x
e e o e e e e
e e o O e e e
e e e e e e e
x x e e e x x
x x e e e x x

You can see that there are initially 4 pegs in the board, and the last peg should end up in the middle of the board. The winning sequence of moves is:

1. (4, 4) to (2, 4)
2. (3, 2) to (3, 4)
3. (2, 4) to (4, 4)

Where coordinates are given as (x, y).

Input

The first line of input is the number of datasets to follow. Each dataset should be processed the same.

The input for each dataset consists of 7 lines; each line consists of 7 characters from the set {x, e, o, E, O} with blanks between them. You are guaranteed that exactly one 'E' or 'O' will appear, and that two or more 'o' or 'O' will appear.

Output

For each dataset, output a line containing the data set number. If a sequence of valid moves exists that leaves only one peg on the board, and leaves that peg in the desired location, print out the sequence of moves, as shown in the above example. If no sequence exists, print "No solution". Leave a blank line between datasets.

Sample Input

2
x x e e e x x
x x o e e x x
e e o e e e e
e e o O e e e
e e e e e e e
x x e e e x x
x x e e e x x
x x e E e e e
x e e e e e e
e e e o o e e
e e e x e e e
e e e e e e e
e e e e e e e
e e e e e e e

Sample Output

Dataset 1:
1. (4, 4) to (2, 4)
2. (3, 2) to (3, 4)
3. (2, 4) to (4, 4)

Dataset 2:

No solution.

// Problem#: 1053
// Submission#: 3456571
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <iomanip>
#include <algorithm>
#include <queue>
#include <functional>
#include <map>
#include <string.h>
#include <math.h>
#include <list>
#include <set>
using namespace std;

int move_p[40], move_d[50], move_j[50], move_l[50];
bool pegs[50], allow[50];
int orig;
int num;
int last;
int next_peg, next_dir;

bool forward_helper(int curr, int dir, int & jump, int & land) {
    const int curr_x = curr % 7;
    const int curr_y = curr / 7;
    int jump_x = curr_x;
    int jump_y = curr_y;
    int land_x = curr_x;
    int land_y = curr_y;
    switch (dir)
       {
       case 0: // left
          jump_x = curr_x - 1;
          land_x = curr_x - 2;
          break;
       case 1: // up
          jump_y = curr_y - 1;
          land_y = curr_y - 2;
          break;
       case 2: // right
          jump_x = curr_x + 1;
          land_x = curr_x + 2;
          break;
       case 3: // down
          jump_y = curr_y + 1;
          land_y = curr_y + 2;
          break;
       }

    // Make sure we didn't jump off the board.
    if ((land_x < 0) || (land_x >= 7) ||
        (land_y < 0) || (land_y >= 7)) return false;

    // It's a winning move.
    jump = jump_x + 7 * jump_y;
    land = land_x + 7 * land_y;
    return true;
}

inline void increment_p() {
    next_dir = 0;
    next_peg++;
}

inline void increment() {
    next_dir++;
    if (next_dir == 4) increment_p(); 
}

bool forward(void) {
    const int index = orig - num;
    if (num == 1) return false;
    while (next_peg < 49) {
        int jump, land;
        if (!pegs[next_peg])
            // Current space is empty. Of course we can't do anything.
            increment_p();
        else if (forward_helper(next_peg, next_dir, jump, land)
            // Make sure:
            // (1) position to be jumped is occupied,
            // (2) position we land in is unoccupied,
            // (3) position we land in is allowed.
                 && pegs[jump] && !pegs[land] && allow[land]) {
            // Save the current state.
            move_p[index] = next_peg;
            move_d[index] = next_dir;
            move_j[index] = jump;
            move_l[index] = land;

            // Make the move.
            pegs[next_peg] = false;
            pegs[jump] = false;
            pegs[land] = true;
            --num;
            next_peg = 0;
            next_dir = 0;

            return true;
         } else increment();
    }

    // No more forward moves are possible.
    return false;
}

inline bool win() {return (num == 1) && pegs[last];}

void print() {
    for (int i = 0; i < orig - 1; ++i) {
        const int orig = move_p[i];
        const int land = move_l[i];
        const int orig_x = orig % 7 + 1;
        const int orig_y = orig / 7 + 1;
        const int land_x = land % 7 + 1;
        const int land_y = land / 7 + 1;
        cout << (i+1) << ". (" << orig_x << ", " << orig_y << ") to (" << land_x << ", " << land_y <<")" << endl;
    }
}

bool backward() {
    const int index = orig - num - 1;
    if (index < 0) return false;

    next_peg = move_p[index];
    next_dir = move_d[index];
    const int jump = move_j[index];
    const int land = move_l[index];
    ++num;
    pegs[next_peg] = true;
    pegs[jump] = true;
    pegs[land] = false;
 
    // Increment.
    increment();

    return true;
}

void go() {
    while (1) {
        if (forward()) {
            if (win()) {
                print();
                return;
            }
        } else if (backward()) {
        } else break;
    }
    cout << "No solution." << endl;
}

int main() {

    std::ios::sync_with_stdio(false);

    int caseNum;
    cin >> caseNum;
    int counter = 1;
    bool firstTime = true;

    while (caseNum--) {
        
        num = 0;
        char c;
        for (int i = 0, index = 0; i < 7; ++i) {
             for (int j = 0; j < 7; ++j, ++index) {
                cin >> c;
                switch (c) {
                   case 'x' : pegs[index] = false; allow[index] = false; break;
                   case 'o' : pegs[index] = true;  allow[index] = true;  break;
                   case 'e' : pegs[index] = false; allow[index] = true;  break;
                   case 'O' : pegs[index] = true;  allow[index] = true;  last = index;
                      break;
                   case 'E' : pegs[index] = false; allow[index] = true;  last = index;
                      break;
                }
            if (pegs[index]) ++num;
            }
        }
        orig = num;
        next_peg = 0;
        next_dir = 0;
        //if (!firstTime) cout << endl;
        cout << "Dataset " << counter++ << ":" << endl;
        go();
        cout << endl;
        firstTime = false;
    }

    return 0;
}                                 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值