1.4.2---The Clocks

来源:互联网 发布:软件导刊投稿 编辑:程序博客网 时间:2024/06/09 19:00
The Clocks
IOI'94 - Day 2
Consider nine clocks arranged in a 3x3 array thusly:
|-------|    |-------|    |-------|    |       |    |       |    |   |   |    |---O   |    |---O   |    |   O   |          |       |    |       |    |       |           |-------|    |-------|    |-------|        A            B            C|-------|    |-------|    |-------||       |    |       |    |       ||   O   |    |   O   |    |   O   ||   |   |    |   |   |    |   |   ||-------|    |-------|    |-------|    D            E            F|-------|    |-------|    |-------||       |    |       |    |       ||   O   |    |   O---|    |   O   ||   |   |    |       |    |   |   ||-------|    |-------|    |-------|    G            H            I

The goal is to find a minimal sequence of moves to return all the dials to 12 o'clock. Nine different ways to turn the dials on the clocks are supplied via a table below; each way is called a move. Select for each move a number 1 through 9 which will cause the dials of the affected clocks (see next table) to be turned 90 degrees clockwise.MoveAffected clocks1ABDE2ABC3BCEF4ADG5BDEFH6CFI7DEGH8GHI9EFHI

Example

Each number represents a time accoring to following table:
9 9 12       9 12 12       9 12 12        12 12 12      12 12 12 6 6 6  5 ->  9  9  9  8->  9  9  9  4 ->  12  9  9  9-> 12 12 12 6 3 6        6  6  6       9  9  9        12  9  9      12 12 12 

[But this might or might not be the `correct' answer; see below.]

PROGRAM NAME: clocks

INPUT FORMAT

Lines 1-3:Three lines of three space-separated numbers; each number represents the start time of one clock, 3, 6, 9, or 12. The ordering of the numbers corresponds to the first example above.

SAMPLE INPUT (file clocks.in)

9 9 126 6 66 3 6

OUTPUT FORMAT

A single line that contains a space separated list of the shortest sequence of moves (designated by numbers) which returns all the clocks to 12:00. If there is more than one solution, print the one which gives the lowest number when the moves are concatenated (e.g., 5 2 4 6 < 9 3 1 1).

SAMPLE OUTPUT (file clocks.out)

4 5 8 9
求最小步数,由于每种变化最多用三次,并且每种变化不分先后顺序,所以问题规模并不大,很容易想到深搜的方法
/*ID:******PROB:clocksLANG:C++*/#include <iostream>#include <fstream>#include <string>using namespace std;int data[4][4]={0},mina=1000,answer[1000],way[1000],count[10];//data用于存储基本时钟数据,mina为结果数列规模,answer用于存储结果数列,way用于标识该步之后用到的最后一种方法的序号,count为每种方法使用的次数void change(int ii)//调时{    if (ii==1)    {        data[1][1]=(data[1][1]+3)%12;        data[1][2]=(data[1][2]+3)%12;        data[2][1]=(data[2][1]+3)%12;        data[2][2]=(data[2][2]+3)%12;    }    else if (ii==2)    {        data[1][1]=(data[1][1]+3)%12;        data[1][2]=(data[1][2]+3)%12;        data[1][3]=(data[1][3]+3)%12;    }    else if (ii==3)    {        data[1][2]=(data[1][2]+3)%12;        data[1][3]=(data[1][3]+3)%12;        data[2][2]=(data[2][2]+3)%12;        data[2][3]=(data[2][3]+3)%12;    }    else if (ii==4)    {        data[1][1]=(data[1][1]+3)%12;        data[2][1]=(data[2][1]+3)%12;        data[3][1]=(data[3][1]+3)%12;    }    else if (ii==5)    {        data[1][2]=(data[1][2]+3)%12;        data[2][1]=(data[2][1]+3)%12;        data[2][2]=(data[2][2]+3)%12;        data[2][3]=(data[2][3]+3)%12;        data[3][2]=(data[3][2]+3)%12;    }    else if (ii==6)    {        data[1][3]=(data[1][3]+3)%12;        data[2][3]=(data[2][3]+3)%12;        data[3][3]=(data[3][3]+3)%12;    }    else if (ii==7)    {        data[2][1]=(data[2][1]+3)%12;        data[2][2]=(data[2][2]+3)%12;        data[3][1]=(data[3][1]+3)%12;        data[3][2]=(data[3][2]+3)%12;    }    else if (ii==8)    {        data[3][1]=(data[3][1]+3)%12;        data[3][2]=(data[3][2]+3)%12;        data[3][3]=(data[3][3]+3)%12;    }    else if (ii==9)    {        data[2][2]=(data[2][2]+3)%12;        data[2][3]=(data[2][3]+3)%12;        data[3][2]=(data[3][2]+3)%12;        data[3][3]=(data[3][3]+3)%12;    }}void dfs(int jj)//深搜{    int iii,jjj;    bool ok=true;//标识时钟是否调整为最终结果       for (iii=1;iii<=3;iii++) //判断目前时状态for (jjj=1;jjj<=3;jjj++) if (data[iii][jjj]!=0) ok=false;    if (ok && jj-1<mina)//如果目前时钟为最终状态    {        mina=jj-1;        for (iii=1;iii<=mina;iii++) answer[iii]=way[iii];    }    else if (!ok && jj-1<mina)//如果目前时钟不为最终状态且目前步数小于已出现过的最终结果最小规模数    {        for (iii=way[jj-1];iii<=9;iii++)        {            if (count[iii]==3) //如果该方法已被使用过三次,则无须再用continue;//尝试使用该方法的情况             change(iii);            count[iii]++;            way[jj]=iii;            dfs(jj+1);//还原到不使用该方法的状态            change(iii);            change(iii);            change(iii);            count[iii]--;        }    }}int main(){    ifstream fin ("clocks.in");    ofstream fout ("clocks.out");    int i,j; memset(count,0,sizeof(count));//初始化count    for (i=1;i<=3;i++)//输入基本时钟数据    for (j=1;j<=3;j++)    {        fin >> data[i][j];        if (data[i][j]==12) data[i][j]=0;    }    way[0]=1;    dfs(1);//输出结果    for (i=1;i<=mina-1;i++) fout << answer[i] << ' ';    fout << answer[mina] << endl;}


代码参考http://blog.sina.com.cn/s/blog_4c396f430100099y.html
原创粉丝点击