poj 1166 拨钟问题 参考USACO 方法

来源:互联网 发布:呱呱社区软件 编辑:程序博客网 时间:2024/04/26 03:50

枚举的一个题,当时看到挺头疼的,后来参考的USACO的方法。用二进制数字来显示钟表的状态,

每个方案转化为二进制存在move数组里,每次拨动让clock和move[i]相加在和CLEAR想与得到状态,然后通过枚举九个循环得出结果。

#include<fstream>
#include<vector>
using namespace std;
typedef long CLOCK;

const long CLEAR=57521883;

const long MOVE[10] = {0,18911232, 19136512, 2363904, 16810048, 2134536, 262657, 36936, 73, 4617};
bool canMatch(CLOCK clocks,vector<int> m);
void initial(ifstream fin,CLOCK clocks);
vector<int> getResult(CLOCK clocks);
int getLength(vector<int> m);
int main(){
ifstream fin("clock.in");
ofstream fout("clock.out");
CLOCK clocks(0);
initial(fin,clocks);
vector<int> result=getResult(clocks);
    for (vector<int>::iterator iter = result.begin(); iter != result.end(); ++iter) {
        fout << *iter;
        if (iter + 1 != result.end())
            fout << ' ';
    }
    fout << endl;
}
void initial(ifstream fin,CLOCK clocks){
int t,tmp;
long bit=16777216;
while(fin>>tmp){
switch(tmp){
case 12 : t = 0;
break;
case 3 : t = 1;
break;
case 6 : t = 2;
break;
case 9 : t = 3;
break;
}
clocks = clocks|(t*bit);
bit/= 8;
}
};
vector<int> getResult(CLOCK clocks){
vector<int> result,m(10,0);
int minLength = 28;
for(int t9 = 0;t9<=3;++t9)
for(int t8 = 0;t8<=3;++t8)
for(int t7 = 0;t7<=3;++t7)
for(int t6 = 0;t6<=3;++t6)
for(int t5 = 0;t5<=3;++t5)
for(int t4 = 0;t4<=3;++t4)
for(int t3 = 0;t3<=3;++t3)
for(int t2 = 0;t2<=3;++t2)
for(int t1 = 0;t1<=3;++t1)
{
m[1] = t1;
m[2] = t2;
m[3] = t3;
m[4] = t4;
m[5] = t5;
m[6] = t6;
m[7] = t7;
m[8] = t8;
m[9] = t9;
if(canMatch(clocks,m))
{
if(getLength(m)<minLength)
{
minLength = getLength(m);
result = m;
}
}
}
return result;
}
int getLength(vector<int> m){
vector<int>::iterator it;
int result(0);
for(it = m.begin();it < m.end();it++)
result += *it;
return result;
}
bool canMatch(CLOCK clocks,vector<int> m){
int cirNum;
for(int i = 1;i <= 9;i++)
{
cirNum = m[i];
while(cirNum--)
{
clocks = (clocks + MOVE[i])&CLEAR;
}
}
return clocks==0;
}
0 0
原创粉丝点击