USACO 1.4 The Clocks

4次同一操作等效于没有操作,操作的顺序不影响结果。
用迭代加深搜索解(貌似效率不高),代码如下:

#include <iostream>
#include 
<fstream>
#include 
<string>

using namespace std;

ifstream fin(
"clocks.in");
ofstream fout(
"clocks.out");

#ifdef _DEBUG
#define out cout
#define in cin
#else
#define out fout
#define in fin
#endif

//op[i][j]为操作i对第j个时钟增加的小时数
int ops[9][9];

string op[9= {
    
"ABDE","ABC","BCEF","ADG","BDEFH","CFI","DEGH","GHI","EFHI"
};

//clocks当前时钟的状态
int clocks[9];
//当前的操作序列
int cur_ops[9];

void pre()
{
    memset(ops,
0,sizeof(ops) );
    memset(cur_ops,
0,sizeof(cur_ops));

    
for(int i=0;i<9;++i){
        
for(int j=0;j<op[i].size();++j){
            ops[i][op[i][j]
-'A'= 3;
        }
    }

}

//执行clocks操作序列
void do_ops()
{
    
for(int i=0;i<9;++i){
        
if(cur_ops[i]!=0)
            
for(int j=0;j<9;++j){
                clocks[j]
+=ops[i][j]*cur_ops[i];
                clocks[j]
%=12;
            }
    }
}

//i为当前到达的操作编号
void dfs(int i, int cur_depth,int max_dep)
{
    
//到达迭代加深搜索的最大深度或i超过最大
    if(cur_depth>max_dep||i>9)
        
return;    

    
if(cur_depth==max_dep){
        
        
//保存当前clocks状态
        int saved[9];
        memcpy(saved,clocks,
sizeof(clocks));

        do_ops();

        
bool valid = true;
        
for(int i=0;i<9;++i){
            
if(clocks[i]!=0){
                valid 
= false;
                
break;
            }
        }

        
if(valid){
            
//时钟全为0,到达可行解
            bool first = true;
            
for(int i=0;i<9;++i){
                
if(cur_ops[i]!=0){
                    
int t = cur_ops[i];
                    
while(t--){
                        
if(first){
                            
out<<i+1;
                            first 
= false;
                        }
else{
                            
out<<" "<<i+1;
                        }
                    }
                }
            }

            
out<<endl;
            exit(
0);
        }
else{
            
//恢复时钟
            memcpy(clocks,saved,sizeof(saved));
            
return;
        }
    }

    
for(int inc=3;inc>=0;inc--){
        
//因为要求最小的序列,优先多分配当前i,再分配后续更大的号
      if(cur_depth+inc<=max_dep&&cur_ops[i]+inc<4){
          cur_ops[i]
+=inc;
          dfs(i
+1,cur_depth+inc,max_dep);
          cur_ops[i]
-=inc;
      } 
    }
}

void solve()
{
    pre();

    
for(int i=0;i<9;++i){
        
in>>clocks[i];
        clocks[i]
%=12;
    }


    
for(int d = 0;d<=3*9;++d){
        dfs(
0,0,d);
    }
}

int main(int argc,char *argv[])
{
  solve();
  
return 0;
}


posted on 2009-06-10 21:56 YZY 阅读(1106) 评论(0)  编辑 收藏 引用 所属分类: AlgorithmUSACO


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2009年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

统计

常用链接

留言簿(2)

随笔分类

随笔档案

搜索

积分与排名

最新评论

阅读排行榜