题目链接:
https://vjudge.net/problem/UVA-1343
题意:
数字1,2,3都有八个,求出最少的旋转次数使得图形中间八个数相同。 旋转规则:对于每一长行或每一长列,每次旋转就是将数据向头的位置移动一位,头上的数放置到尾部。若次数相同,则找出字典序最小旋转次序。 输入是从上到下,从左向右,注意方向
题解:
代码:
#include <bits/stdc++.h>
using namespace std;
typedef
long long ll;
#define MS(a) memset(a,0,sizeof(a))
#define MP make_pair
#define PB push_back
const int INF =
0x3f3f3f3f;
const ll INFLL =
0x3f3f3f3f3f3f3f3fLL;
inline ll read(){
ll x=
0,f=
1;
char ch=getchar();
while(ch<
'0'||ch>
'9'){
if(ch==
'-')f=-
1;ch=getchar();}
while(ch>=
'0'&&ch<=
'9'){x=x*
10+ch-
'0';ch=getchar();}
return x*f;
}
const int maxn =
1e5+
10;
int maxd,ok,a[
50];
char ans[maxn];
int line[
8][
7] = {
{
0,
2,
6,
11,
15,
20,
22},
{
1,
3,
8,
12,
17,
21,
23},
{
10,
9,
8,
7,
6,
5,
4},
{
19,
18,
17,
16,
15,
14,
13}
};
int rev[
8] = {
5,
4,
7,
6,
1,
0,
3,
2};
int final[
8] = {
6,
7,
8,
11,
12,
15,
16,
17};
void init(){
for(
int i=
4; i<
8; i++)
for(
int j=
0; j<=
6; j++)
line[i][j] = line[rev[i]][
6-j];
}
bool is_final(){
int k = a[final[
0]];
for(
int i=
1; i<
8; i++)
if(a[final[i]]!=k)
return false;
return true;
}
void move(
int k){
int tmp = a[line[k][
0]];
for(
int i=
1; i<
7; i++)
a[line[k][i-
1]] = a[line[k][i]];
a[line[k][
6]] = tmp;
}
int diff(
int x){
int cnt =
0;
for(
int i=
0; i<
8; i++)
if(x != a[final[i]])
cnt++;
return cnt;
}
int h(){
return min(min(diff(
1),diff(
2)),diff(
3));
}
void dfs(
int cur){
if(is_final()){
ans[cur] =
'\0';
cout << ans << endl;
ok =
1;
return ;
}
if(cur+h() > maxd)
return ;
for(
int i=
0; i<
8; i++){
ans[cur] =
'A'+i;
move(i);
dfs(cur+
1);
if(ok)
return ;
move(rev[i]);
}
}
int main(){
init();
while(scanf(
"%d",&a[
0]) && a[
0]){
for(
int i=
1; i<
24; i++) a[i]=read();
ok =
0;
if(is_final())
puts(
"No moves needed");
else{
for(maxd=
1; ; maxd++){
dfs(
0);
if(ok)
break;
}
}
cout << a[
6] << endl;
}
return 0;
}
转载请注明原文地址: https://ju.6miu.com/read-35939.html