AOJ 0503: Cup
再帰する式を作れれば解けます。右シフトすると一番小さいカップが消えてくれて、他のカップが1つづつ小さくなります。
ステップをトレースする解法が想定解らしいですが、集合で解く方が楽です(トレースしようとして失敗しました)
#include <algorithm> #include <iostream> using namespace std; int n,m; int toC(int A,int B,int C){ if(!A&&!B)return 0; if(C&1)return toC(A>>1,B>>1,C>>1); if(B&1)return toC(C>>1,B>>1,A>>1)+toC((A|B|C)>>1,0,0)+1; if(A&1)return toC(A>>1,B>>1,C>>1)+2*toC((A|B|C)>>1,0,0)+2; //cerr<<"ERROR"<<endl; //return -2; } int main(){ while(cin>>n>>m,n||m){ int cup[3] = {0}; for(int i = 0; i < 3; i++){ int t; cin>>t; for(int j = 0; j < t; j++){ int a; cin>>a; cup[i] |= 1<<a-1; } } int a = min(toC(cup[0],cup[1],cup[2]),toC(cup[2],cup[1],cup[0])); cout<<(a<=m?a:-1)<<endl; } return 0; }