ITON

来源:互联网 发布:淘宝可以延长几天收货 编辑:程序博客网 时间:2024/06/15 08:55

关于标题

I(Interesting)T(Test)O(Of)N(Noip)


番外(论矩阵的妙用)

一道USACO的题:

The Clocks【搜索专题】

题目背景
USACO 1.4.2 (IOI’94)
搜索专题训练(一)

题目描述
考虑将如此安排在一个 3×3 行列中的九个时钟:

这里写图片描述

目标要找一个最小的移动顺序次将所有的指针指向12点.
下面原表格列出了 9 种不同的旋转指针的方法,每一种方法都叫一次移动。
选择 1 到 9 号移动方法,将会使在表格中对应的时钟的指针顺时针旋转90度。

移动方法 —– 受影响的时钟
— 1 ————— ABDE —–
— 2 ————— ABC ——
— 3 ————— BCEF ——
— 4 ————— ADG ——
— 5 ————– BDEFH —–
— 6 ————— CFI ——–
— 7 ————— DEGH —–
— 8 ————— GHI ——–
— 9 ————— EFHI ——–
比如一个例子:

这里写图片描述

但这可能不是正确的方法,请看下面。

输入格式
第 1-3 行:三个空格分开的数字,每个数字表示一个时钟的初始时间:3,6,9,12。
数字的含意和上面第一个例子一样。

输出格式
单独的一行包括一个用空格分开的将所有指针指向 12:00 的最短移动顺序的列表。
如果有多种方案,输出那种使的连接起来数字最小的方案。(举例来说:5 2 4 6 < 9 3 1 1)。

样例数据 1
输入  [复制]

9 9 12
6 6 6
6 3 6
输出

4 5 8 9
这是我同学SZM的代码:

SZM.CPP

#include<bits/stdc++.h>using namespace std;int f[500005][4][4],num[4][4],done[500005],pre[500005];int head,tail,ans=0;bool p[4][4][4][4][4][4][4][4][4];bool flag=false;inline int add(int x){    x=x+1;    if(x==4) return 0;    else return x;}inline void work1(int x){    int a[4][4];    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            a[t][h]=f[x][t][h];        }    }    a[1][1]=add(a[1][1]);    a[1][2]=add(a[1][2]);    a[2][1]=add(a[2][1]);    a[2][2]=add(a[2][2]);    bool fuck=true;    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            if(a[t][h]!=3)            {                fuck=false;                break;            }        }        if(fuck==false) break;    }    if(fuck==true)    {        int now=x,q[22],val=0;        flag=true;        q[++val]=1;        if(x!=1)    q[++val]=done[x];        while(pre[now]!=0)        {            now=pre[now];            if(done[now]!=0)            {                q[++val]=done[now];            }        }        for(int t=val;t>=1;--t)             cout<<q[t]<<' ';    }    if(!p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]])    {        p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]]=true;        ++tail;        for(int t=1;t<=3;++t)        {            for(int h=1;h<=3;++h)            {                f[tail][t][h]=a[t][h];                if(a[t][h]>3) ans++;            }        }        pre[tail]=x,done[tail]=1;    }}inline void work2(int x){    int a[4][4];    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            a[t][h]=f[x][t][h];        }    }    a[1][1]=add(a[1][1]);    a[1][2]=add(a[1][2]);    a[1][3]=add(a[1][3]);    bool fuck=true;    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            if(a[t][h]!=3)            {                fuck=false;                break;            }        }        if(fuck==false) break;    }    if(fuck==true)    {        int now=x,q[22],val=0;        flag=true;        q[++val]=2;        if(x!=1)q[++val]=done[x];        while(pre[now]!=0)        {            now=pre[now];            if(done[now]!=0)            {                q[++val]=done[now];            }        }        for(int t=val;t>=1;t--) cout<<q[t]<<' ';    }    if(!p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]])    {        p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]]=true;        tail++;        for(int t=1;t<=3;++t)        {            for(int h=1;h<=3;++h)            {                f[tail][t][h]=a[t][h];            }        }        pre[tail]=x,done[tail]=2;    }}void work3(int x){    int a[4][4];    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            a[t][h]=f[x][t][h];        }    }    a[1][2]=add(a[1][2]);    a[1][3]=add(a[1][3]);    a[2][2]=add(a[2][2]);    a[2][3]=add(a[2][3]);    bool fuck=true;    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            if(a[t][h]!=3)            {                fuck=false;                break;            }        }        if(fuck==false) break;    }    if(fuck==true)    {        int now=x,q[22],val=0;        flag=true;        q[++val]=3;        if(x!=1)q[++val]=done[x];        while(pre[now]!=0)        {            now=pre[now];            if(done[now]!=0)            {                q[++val]=done[now];            }        }        for(int t=val;t>=1;t--) cout<<q[t]<<' ';    }    if(!p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]])    {        p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]]=true;        tail++;        for(int t=1;t<=3;++t)        {            for(int h=1;h<=3;++h)            {                f[tail][t][h]=a[t][h];            }        }        pre[tail]=x,done[tail]=3;    }}void work4(int x){    int a[4][4];    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            a[t][h]=f[x][t][h];        }    }    a[1][1]=add(a[1][1]);    a[2][1]=add(a[2][1]);    a[3][1]=add(a[3][1]);    bool fuck=true;    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            if(a[t][h]!=3)            {                fuck=false;                break;            }        }        if(fuck==false) break;    }    if(fuck==true)    {        int now=x,q[22],val=0;        flag=true;        q[++val]=4;        if(x!=1)q[++val]=done[x];        while(pre[now]!=0)        {            now=pre[now];            if(done[now]!=0)            {                q[++val]=done[now];            }        }        for(int t=val;t>=1;t--) cout<<q[t]<<' ';    }    if(!p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]])    {        p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]]=true;        tail++;        for(int t=1;t<=3;++t)        {            for(int h=1;h<=3;++h)            {                f[tail][t][h]=a[t][h];            }        }        pre[tail]=x,done[tail]=4;    }}void work5(int x){    int a[4][4];    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            a[t][h]=f[x][t][h];        }    }    a[1][2]=add(a[1][2]);    a[2][1]=add(a[2][1]);    a[2][2]=add(a[2][2]);    a[2][3]=add(a[2][3]);    a[3][2]=add(a[3][2]);    bool fuck=true;    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            if(a[t][h]!=3)            {                fuck=false;                break;            }        }        if(fuck==false) break;    }    if(fuck==true)    {        int now=x,q[22],val=0;        flag=true;        q[++val]=5;        if(x!=1)q[++val]=done[x];        while(pre[now]!=0)        {            now=pre[now];            if(done[now]!=0)            {                q[++val]=done[now];            }        }        for(int t=val;t>=1;t--) cout<<q[t]<<' ';    }    if(!p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]])    {        p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]]=true;        tail++;        for(int t=1;t<=3;++t)        {            for(int h=1;h<=3;++h)            {                f[tail][t][h]=a[t][h];            }        }        pre[tail]=x,done[tail]=5;    }}void work6(int x){    int a[4][4];    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            a[t][h]=f[x][t][h];        }    }    a[1][3]=add(a[1][3]);    a[2][3]=add(a[2][3]);    a[3][3]=add(a[3][3]);    bool fuck=true;    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            if(a[t][h]!=3)            {                fuck=false;                break;            }        }        if(fuck==false) break;    }    if(fuck==true)    {        int now=x,q[22],val=0;        flag=true;        q[++val]=6;        if(x!=1)q[++val]=done[x];        while(pre[now]!=0)        {            now=pre[now];            if(done[now]!=0)            {                q[++val]=done[now];            }        }        for(int t=val;t>=1;t--) cout<<q[t]<<' ';    }    if(!p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]])    {        p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]]=true;        tail++;        for(int t=1;t<=3;++t)        {            for(int h=1;h<=3;++h)            {                f[tail][t][h]=a[t][h];            }        }        pre[tail]=x,done[tail]=6;    }}void work7(int x){    int a[4][4];    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            a[t][h]=f[x][t][h];        }    }    a[2][1]=add(a[2][1]);    a[2][2]=add(a[2][2]);    a[3][1]=add(a[3][1]);    a[3][2]=add(a[3][2]);    bool fuck=true;    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            if(a[t][h]!=3)            {                fuck=false;                break;            }        }        if(fuck==false) break;    }    if(fuck==true)    {        int now=x,q[22],val=0;        flag=true;        q[++val]=7;        if(x!=1)q[++val]=done[x];        while(pre[now]!=0)        {            now=pre[now];            if(done[now]!=0)            {                q[++val]=done[now];            }        }        for(int t=val;t>=1;t--) cout<<q[t]<<' ';    }    if(!p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]])    {        p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]]=true;        tail++;        for(int t=1;t<=3;++t)        {            for(int h=1;h<=3;++h)            {                f[tail][t][h]=a[t][h];            }        }        pre[tail]=x,done[tail]=7;    }}void work8(int x){    int a[4][4];    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            a[t][h]=f[x][t][h];        }    }    a[3][1]=add(a[3][1]);    a[3][2]=add(a[3][2]);    a[3][3]=add(a[3][3]);    bool fuck=true;    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            if(a[t][h]!=3)            {                fuck=false;                break;            }        }        if(fuck==false) break;    }    if(fuck==true)    {        int now=x,q[22],val=0;        flag=true;        q[++val]=8;        if(x!=1)q[++val]=done[x];        while(pre[now]!=0)        {            now=pre[now];            if(done[now]!=0)            {                q[++val]=done[now];            }        }        for(int t=val;t>=1;t--) cout<<q[t]<<' ';    }    if(!p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]])    {        p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]]=true;        tail++;        for(int t=1;t<=3;++t)        {            for(int h=1;h<=3;++h)            {                f[tail][t][h]=a[t][h];            }        }        pre[tail]=x,done[tail]=8;    }}void work9(int x){    int a[4][4];    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            a[t][h]=f[x][t][h];        }    }    a[2][2]=add(a[2][2]);    a[2][3]=add(a[2][3]);    a[3][2]=add(a[3][2]);    a[3][3]=add(a[3][3]);    bool fuck=true;    for(int t=1;t<=3;++t)    {        for(int h=1;h<=3;++h)        {            if(a[t][h]!=3)            {                fuck=false;                break;            }        }        if(fuck==false) break;    }    if(fuck==true)    {        int now=x,q[22],val=0;        flag=true;        q[++val]=9;        if(x!=1)q[++val]=done[x];        while(pre[now]!=0)        {            now=pre[now];            if(done[now]!=0)            {                q[++val]=done[now];            }        }        for(int t=val;t>=1;t--) cout<<q[t]<<' ';    }    if(!p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]])    {        p[a[1][1]][a[1][2]][a[1][3]][a[2][1]][a[2][2]][a[2][3]][a[3][1]][a[3][2]][a[3][3]]=true;        tail++;        for(int t=1;t<=3;++t)        {            for(int h=1;h<=3;++h)            {                f[tail][t][h]=a[t][h];            }        }        pre[tail]=x,done[tail]=9;    }}int main(){    int bb;    memset(p,false,sizeof(p));    for(int i=1;i<=3;i++)    {        for(int j=1;j<=3;j++)        {            scanf("%d",&bb);            num[i][j]=bb/3-1;        }    }    p[num[1][1]][num[1][2]][num[1][3]][num[2][1]][num[2][2]][num[2][3]][num[3][1]][num[3][2]][num[3][3]]=true;    head=0,tail=1,pre[tail]=0,done[tail]=0;    for(int i=1;i<=3;i++)    {        for(int j=1;j<=3;j++)        {            f[tail][i][j]=num[i][j];        }    }    while(head<tail)    {        head++;        work1(head);        if(flag==true) break;        work2(head);        if(flag==true) break;        work3(head);        if(flag==true) break;        work4(head);        if(flag==true) break;        work5(head);        if(flag==true) break;        work6(head);        if(flag==true) break;        work7(head);        if(flag==true) break;        work8(head);        if(flag==true) break;        work9(head);        if(flag==true) break;    }    return 0;}

500行的代码不知道他是以怎样的毅力打完的。。。
反正我是看着都晕。。
下面是标准std算法:

STD.CPP

#include<iostream>#include<cstdio>#include<cstdlib>#include<cmath>#include<algorithm>#include<string>#include<cstring>#include<queue>using namespace std;#define MAXSTEPS 30const int a[9][9]={    {1,1,0,1,1,0,0,0,0},    {1,1,1,0,0,0,0,0,0},    {0,1,1,0,1,1,0,0,0},    {1,0,0,1,0,0,1,0,0},    {0,1,0,1,1,1,0,1,0},    {0,0,1,0,0,1,0,0,1},    {0,0,0,1,1,0,1,1,0},    {0,0,0,0,0,0,1,1,1},    {0,0,0,0,1,1,0,1,1},};int now[9],minstep;int path[MAXSTEPS],time[9];int init(){    int i,k;    for(i=0; i<9; i++)    {        scanf("%d",&k);;        now[i]=(k/3)%4;    }    memset(path,0,sizeof(path));    memset(time,0,sizeof(time));}int ok(){    int i;    for(i=0; i<9; i++)        if(now[i]%4!=0)return 0;    return 1;}void output(){    int i;    for(i=0;i<minstep-1;i++)    cout<<path[i]+1<<" ";    cout<<path[minstep-1]+1<<endl;}void change(int i){    int j;    for(j=0; j<9; j++)        now[j]+=a[i][j];}void regain(int i){    int j;    for(j=0; j<9; j++)        now[j]-=a[i][j];}void search(int step){    int i,j;    if(step>=MAXSTEPS) return;    if(ok())    {        minstep=step;        output();        return;    }    if (step==0) j=0;    else if(time[path[step-1]]<3) j=path[step-1];    else        j=path[step-1]+1;    for(i=j; i<9; i++)    {        change(i);        time[i]++;        path[step]=i;        search(step+1);        regain(i);        time[i]--;    }}int main(void){    init();    search(0);    return 0;}

正片开始 ↓ ↓ ↓
国外某大佬的代码(引用自http://blog.csdn.net/dyllove98/article/details/9002826):

WTF.CPP

//??????ans from web#include <stdio.h>int a[9][9]= { {3,3,3,3,3,2,3,2,0},               {2,3,2,3,2,3,1,0,1},               {3,3,3,2,3,3,0,2,3},               {2,3,1,3,2,0,2,3,1},               {2,3,2,3,1,3,2,3,2},               {1,3,2,0,2,3,1,3,2},               {3,2,0,3,3,2,3,3,3},               {1,0,1,3,2,3,2,3,2},               {0,2,3,2,3,3,3,3,3} };int v[9];int main() {    int i,j,k;    for (i=0; i<9; i++) {        scanf("%d",&k);        for(j=0; j<9; j++)             v[j]=(v[j]+(4-k/3)*a[i][j])%4;    }    fclose(stdin);    k=0;    for (i=0; i<9; i++)        for (j=0; j<v[i]; j++)            if (!k) { printf("%d",i+1); k=1; }            else    printf(" %d",i+1);    printf("\n");    fclose(stdout);    return 0;}

自己感受一下(T_T)(我则根本没打出来)