poj 1166

 

原题:

                                                                                                 The Clocks
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 5426Accepted: 2036

Description

|-------|    |-------|    |-------|

| | | | | | |
|---O | |---O | | O |
| | | | | |
|-------| |-------| |-------|
A B C

|-------| |-------| |-------|
| | | | | |
| O | | O | | O |
| | | | | | | | |
|-------| |-------| |-------|
D E F

|-------| |-------| |-------|
| | | | | |
| O | | O---| | O |
| | | | | | | |
|-------| |-------| |-------|
G H I
(Figure 1)

There are nine clocks in a 3*3 array (figure 1). The goal is to return all the dials to 12 o'clock with as few moves as possible. There are nine different allowed ways to turn the dials on the clocks. Each such way is called a move. Select for each move a number 1 to 9. That number will turn the dials 90' (degrees) clockwise on those clocks which are affected according to figure 2 below.
Move   Affected clocks


1 ABDE
2 ABC
3 BCEF
4 ADG
5 BDEFH
6 CFI
7 DEGH
8 GHI
9 EFHI
(Figure 2)

Input

Your program is to read from standard input. Nine numbers give the start positions of the dials. 0=12 o'clock, 1=3 o'clock, 2=6 o'clock, 3=9 o'clock.

Output

Your program is to write to standard output. Output a shortest sorted sequence of moves (numbers), which returns all the dials to 12 o'clock. You are convinced that the answer is unique.

Sample Input

3 3 0
2 2 2
2 1 2

Sample Output

4 5 8 9

刚刚AC了这道简单搜索,写点东西巩固一下! 这里我用了个数据结构的小技巧,以前碰到这样的多种选择时总要写一大堆 if else 。这里用了个二维数组来记录每个move操作对每个clock的影响,之后只要扫描这个数组就可以使clock 做相应的变化。我在这里使用的是典型的DFS,从第一个move操作开始搜索,用Oper_C数组记录每个move操作的使用次数,并及时判断是否达到目标状态,是则输出答案退出搜索,否则继续进行下一层搜索。这里每个move操作最多使用三次。

参考代码:( 我这个算法用了125MS,在网上看到有用状态压缩做的,请到访的高手赐教,谢谢!)

//1166 The Clocks
#include <iostream>
using namespace std;
const int move[9][9] = {
{1, 1, 0, 1, 1, 0, 0, 0, 0},// 1th move
{1, 1, 1, 0, 0, 0, 0, 0, 0},// 2th move
{0, 1, 1, 0, 1, 1, 0, 0, 0},// 3th move
{1, 0, 0, 1, 0, 0, 1, 0, 0},// 4th move
{0, 1, 0, 1, 1, 1, 0, 1, 0},// 5th move
{0, 0, 1, 0, 0, 1, 0, 0, 1},// 6th move
{0, 0, 0, 1, 1, 0, 1, 1, 0},// 7th move
{0, 0, 0, 0, 0, 0, 1, 1, 1},// 8th move
{0, 0, 0, 0, 1, 1, 0, 1, 1} // 9th move
};
bool finished;
int Oper_C[9], Clock[9];
bool ok()
{
int tmp[9];
for(int i = 0; i < 9; i++)
   tmp[i] = Clock[i];
for(int j = 0; j < 9; j++)
   for(int i = 0; i < 9; i++)
    tmp[j] = (tmp[j] + move[i][j] * Oper_C[i]) % 4;
for(int i = 0; i < 9; i++)
   if(tmp[i] != 0)
    return 0;
return 1;
}
void print()
{
for(int i = 0; i < 9; i++)
   for(int j = 0; j < Oper_C[i]; j++)
    printf("%d ", i + 1);
printf("/n");
  
}
//pos 是move的序号
void dfs_Clock(int pos)
{
  
   if( ok() )
    {
       finished = 1;
       print();
       return ;       
    }
   if( pos>=9 )    
    {
       return ;         
    }
   for(int i=0;i<4;i++)
    {
       Oper_C[pos] = i;
       dfs_Clock(pos+1);  
       if( finished )
          return ;   
    }
}
int main(void)
{
for(int i = 0; i < 9; i++)
   cin >> Clock[i];  
memset(Oper_C, 0 , sizeof(Oper_C));
    finished = 0;
dfs_Clock(0);
system("pause");
return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值