Particle

競技プログラミングについての雑記

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;
}