http://ace.delos.com/usacoprob2?S=clocks&a=3hMw0XdJ4KO

1每种变换方法可以使用0~3次，因为如果使用4的话，正好转一圈，和0等效。

2并且每种变换方法在前与在后是等效的。所以根据题目输出要求，最小字典序。

/*
ID:liuweiv2
PROG:clocks
LANG:C++
*/
#include<iostream>
using namespace std;
#include<fstream>

int orig[3][3];
int temp[3][3];
int path[28];
int count[28];
ifstream infile;
ofstream outfile;

void copy(){
for(int i=0;i<3;i++)
for(int j = 0;j<3;j++)
temp[i][j] = orig[i][j];
}

if(c == '\0')
return false;

int p ;
p  = 3;
else
p  = -3;
int t = c - 'A';
int i = t/3;
int j = t%3;
temp[i][j]+=p;
if(temp[i][j] == 15)
temp[i][j] = 3;
if(temp[i][j] == 0)
temp[i][j] = 12;

return true;
}

for(int i=0;i<6;i++)
break;
}

void print(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
cout<<temp[i][j]<<" ";
cout<<endl;
}
cout<<endl;
}

bool check(){
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
if(temp[i][j]!=12)
return false;
return true;
}

bool isFind = false;

void dfs(int step,int max){
if(isFind)
return;

if(step>max){

//到达叶子节点，检查
copy();
for(int i=1;i<step;i++)
change(path[i],true);
if(check()){

isFind = true;
outfile<<path[1];
for(int i=2;i<step;i++)
outfile<<" "<<path[i];
outfile<<endl;

}
return ;
}

int i;
if(step == 1)
i  = 1;
else
i = path[step-1];

for(;i<=9;i++){
if(isFind)
return;

path[step] = i;
count[i]++;

if(count[i] == 4){
count[i]--;
continue;
}

dfs(step+1,max);

count[i]--;

}

return;
}
int main(){

infile.open("clocks.in");
outfile.open("clocks.out");
//memset(count,0,sizeof(count));

for(int i=0;i<3;i++)
for(int j = 0;j<3;j++)
infile>>orig[i][j];

for(int i=1;i<=27;i++){
if(isFind)
break;
dfs(1,i);
}

return 0;
}



Executing...
Test 1: TEST OK [0.000 secs, 3344 KB]
Test 2: TEST OK [0.000 secs, 3344 KB]
Test 3: TEST OK [0.022 secs, 3344 KB]
Test 4: TEST OK [0.032 secs, 3344 KB]
Test 5: TEST OK [0.022 secs, 3344 KB]
Test 6: TEST OK [0.119 secs, 3344 KB]
Test 7: TEST OK [0.119 secs, 3344 KB]
Test 8: TEST OK [0.162 secs, 3344 KB]
Test 9: TEST OK [0.119 secs, 3344 KB]

All tests OK.

posted on 2012-05-16 00:49  geeker  阅读(317)  评论(0编辑  收藏  举报