A Different Task UVA - 10795
题意:
汉诺塔的变式,给你一个初态,要求你达到终态。
思路:
- 先找到一个编号最大的,且不能在目标柱子上的k。
- 代码如下
ans = f(start, k-1, 6-start[k]-finish[k])
+ f(finish, k-1, 6-start[k]-finish[k]) +1;
- 大于k的可以当作不存在。
- 那么小于k的先借助中转移动,之后移动k,最后再移成终态(对称性)。
- f里的写法。
if(i==0)return 0;
if(p[i] == fina)return f(p,i-1,fina);///fina码歪了
else return f(p,i-1,6-p[i]-fina) + (1LL<<(i-1));
AC
#include <iostream>
#include <bits/stdc++.h>
#define For(i,x,y) for(int i=(x); i<=(y); i++)
#define fori(i,x,y) for(int i=(x); i<(y); i++)
#define rep(i,y,x) for(int i=(y); i>=(x); i--)
#define mst(x,a) memset(x,a,sizeof(x))
#define pb push_back
#define sz(a) (int)a.size()
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int>pa;
typedef pair<ll,ll>pai;
const int maxn = 66;
int finish[maxn], start[maxn];
ll f(int *p, int i, int fina){
if(i==0)return 0;
if(p[i] == fina)return f(p,i-1,fina);///fina码歪了
else return f(p,i-1,6-p[i]-fina) + (1LL<<(i-1));
}
int main()
{
int n, caseno = 0;//ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
while(scanf("%d", &n)&&n){
For(i,1,n)scanf("%d", &start[i]);
For(i,1,n)scanf("%d", &finish[i]);
int k=n;
while(k>=1 && start[k] == finish[k])k--;
ll ans = 0;
if(k>=1)ans = f(start, k-1, 6-start[k]-finish[k]) + f(finish, k-1, 6-start[k]-finish[k]) +1;
printf("Case %d: %lld\n", ++caseno, ans);
}///没加ll 又见了回祖宗。
return 0;
}