这是一道Hanio Tower的变形题
要按绩点从低到高处理:
- 如果他已在目标位置,那么不动;
- 如果他要从计算机(数学)到中文,或者从中文到计算机(数学),那么首先把绩点更高的人移到数学(计算机),这部分递归做,然后实现转系;
- 如果他要从计算机(数学)到数学(计算机),那么就相当于先做从计算机(数学)到中文,再做从中文到数学(计算机);
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> typedef long long ll; using namespace std; struct Point{ int s,t; double gpa; }p[30]; ll sum[30]; int n; int change(char * s){ if(s[0]=='M')return 1; else if(s[1]=='h')return 0; else return 2; } bool cmp(struct Point a,struct Point b){ return a.gpa>b.gpa; } void init(){ int i; sum[0]=0; for(i=1;i<=20;i++) sum[i]=sum[i-1]*3+1; //这里计算的是那个从计算机(数学)到中文或者n个从中文到计算机(数学)转移的步骤 } ll dfs(int pos,int s,int t){ if(pos==-1) return 0; if(s!=-1 && t!=-1){ if(s==0 || t==0) return sum[pos+1]; return sum[pos+1]*2; } int ss,tt; if(s==-1) ss=p[pos].s; else ss=s; if(t==-1) tt=p[pos].t; else tt=t; if(ss==tt) return dfs(pos-1,s,t); else if(ss!=0 && tt!=0) return dfs(pos-1,s,tt)+dfs(pos-1,tt,0)+dfs(pos-1,0,ss)+dfs(pos-1,ss,t)+2; else return dfs(pos-1,s,3-tt-ss)+1+dfs(pos-1,3-tt-ss,t); } int main(){ int i,j; double gpa; char s1[30],s2[30]; init(); while(scanf("%d",&n)!=EOF){ for(i=0;i<n;i++){ scanf("%s %s %lf",s1,s2,&gpa); p[i].s=change(s1); p[i].t=change(s2); p[i].gpa=gpa; } sort(p,p+n,cmp); printf("%lld\n",dfs(n-1,-1,-1)); } return 0; }