USACO1.4 The Clocks 解题报告

来源:互联网 发布:韩国乐天免税店有mac吗 编辑:程序博客网 时间:2024/05/16 12:16

第一次用BFS,以前只是会用递归的DFS搜索,这次对照着书,硬生生的把BFS打出来了,终于明白什么叫做复杂度了。

先上程序(很明显这题的BFS会很痛苦,因为第一层9个,第二层9×9,第三层9×9×9,大约到了8层的时候,无论是什么样的队列,还是堆栈都不崩溃了)

很悲惨,到了第三组数据的时候完全不可能通过了,队列溢出了。实在无法达到35亿的储存效果。希望和我一样遇到这个问题的小白注意一下子。

#include<stdio.h>#include<iostream>#include<string.h>#include<fstream>using namespace std;char means[10][6]= {"","ABDE","ABC","BCEF","ADG","BDEFH","CFI","DEGH","GHI","EFHI"};int clockx[10],t[11];int queue[3000000][11];long long int qs=0,qe=0;int stack[1000],sp=0;int p;int inthequeue(int t[]){    int flag=1;    for(int i=0;i<=qe&&flag;i++)        for(int j=1;j<=9&&flag;j++)            if(t[j]!=queue[i][j])                flag=0;    return flag;}int check(int t[10]){    int flag=1;    for(int i=1; i<=9&&flag; i++)        if(t[i]!=12)    flag=0;    return flag;}int main(){    int i,j,flag=1;    ifstream cin("clocks.in");    ofstream cout("clocks.out");    for(i=1; i<=9; i++)        cin>>clockx[i];    for(j=1; j<=10; j++)        queue[qs][j]=clockx[j];    queue[qe][0]=0;    qe++;    for(j=1; j<=9; j++)  t[j]=queue[qs][j];    while(1)    {        for(i=1; i<=9; i++)        {            for(j=1; j<=9; j++)  t[j]=            queue[qs][j];            for(j=0; j<strlen(means[i]); j++)            {                p=means[i][j]-'A'+1;                t[p]+=3;                if(t[p]>12) t[p]=3;            }            if(inthequeue(t));            else{for(j=1; j<=10; j++)                queue[qe][j]=t[j];            queue[qe][0]=qs;            queue[qe][10]=i;}            if(check(t))            {                flag=0;                break;            }            qe++;        }        if(!flag)   break;        qs++;    }    j=queue[qe][0];    stack[sp]=queue[qe][10];    sp++;    while(j!=0)    {        stack[sp]=queue[j][10];        sp++;        j=queue[j][0];    }    for(j=sp-1; j>0; j--)        cout<<stack[j]<<" ";    cout<<stack[0]<<endl;    return 0;}

然后呢,难以剪枝的BFS最终还是被我放弃了,参考了一下网上各位大牛的思路。

貌似这一题是90年代IOI上的题目,还是poj上的原题,写出解题报告的大牛真不少。

一位大牛所说,需要使用高斯消去定理(我汗。这个真不会),还有一位大牛说,需要用到线性代数里面的矩阵(想想也是啊,可是。。线代我也不会。。),最后一位OI同学提到了可以直接枚举就可以解决问题,我也仔细一想,果然,仅仅是3^9的复杂度,每次旋转九十度,只与次数(0.1.2.3次)有关,不和顺序有关。所以我就有了这样很娱乐的方法。。如此做来相当飘逸。。

#include<iostream>#include<string.h>#include<fstream>using namespace std;char means[10][6]= {"","ABDE","ABC","BCEF","ADG","BDEFH","CFI","DEGH","GHI","EFHI"};int clocks[10],t[11];int x[10];int check(int t[10]){    int flag=1;    for(int i=1; i<=9&&flag; i++)        if(t[i]!=12)    flag=0;    return flag;}int main(){    int i,j,k,p;    ifstream cin("clocks.in");    ofstream cout("clocks.out");    for(i=1; i<=9; i++)        cin>>clocks[i];    for(x[1]=0; x[1]<=3; x[1]++)     for(x[2]=0; x[2]<=3; x[2]++)      for(x[3]=0; x[3]<=3; x[3]++)       for(x[4]=0; x[4]<=3; x[4]++)        for(x[5]=0; x[5]<=3; x[5]++)         for(x[6]=0; x[6]<=3; x[6]++)          for(x[7]=0; x[7]<=3; x[7]++)           for(x[8]=0; x[8]<=3; x[8]++)            for(x[9]=0; x[9]<=3; x[9]++)            {                for(j=1; j<=9; j++)  t[j]=clocks[j];                for(i=1; i<=9; i++)                    for(k=1; k<=x[i]; k++)                    for(j=0; j<strlen(means[i]); j++)                    {                        p=means[i][j]-'A'+1;                        t[p]+=3;                        if(t[p]>12) t[p]=3;                    }                    if(check(t))                    {                        i=1;                        while(x[i]==0)  i++;                        cout<<i;                        for(j=2; j<=x[i]; j++)                            cout<<" "<<i;                        for(i++; i<=9; i++)                        {                            for(j=1; j<=x[i]; j++)                                cout<<" "<<i;                        }                        cout<<endl;                        return 0;                    }            }    return 0;}

感觉不用BFS实在对不住这道题目。。我会慢慢学习大牛的BFS算法是如何炉火纯青的。

原创粉丝点击