DELETED SRM/549-U/1A.cpp
Index: SRM/549-U/1A.cpp
==================================================================
--- SRM/549-U/1A.cpp
+++ SRM/549-U/1A.cpp
@@ -1,204 +0,0 @@
-#include <iostream>
-#include <sstream>
-#include <iomanip>
-#include <vector>
-#include <string>
-#include <map>
-#include <set>
-#include <algorithm>
-#include <numeric>
-#include <iterator>
-#include <functional>
-#include <complex>
-#include <queue>
-#include <stack>
-#include <cmath>
-#include <cassert>
-using namespace std;
-typedef long long LL;
-typedef long double LD;
-typedef complex<LD> CMP;
-
-typedef int           vert;
-typedef vert          edge;
-typedef vector<edge>  edges;
-typedef vector<edges> graph;
-
-bool augment( graph& G, int v, vector<vert>& matchTo, bool visited[] )
-{
-	for(int i=0; i<G[v].size(); ++i) {
-		vert u = G[v][i];
-		if( visited[u] ) continue;
-		visited[u] = true;
-
-		if( matchTo[u]<0 || augment(G, matchTo[u], matchTo, visited) )
-			{ matchTo[v]=u, matchTo[u]=v; return true; }
-	}
-	return false;
-}
-
-template<int NV>
-int biMatch( graph& G, int L ) // [0,L):left, [L,?):right
-{
-	vector<vert> matchTo(G.size(), -1);
-	int ans = 0;
-	for(vert v=0; v<L; ++v) {
-		bool visited[NV] = {};
-		if( augment(G, v, matchTo, visited) )
-			++ans;
-	}
-	return ans;
-}
-
-class PointyWizardHats { public:
-	int getNumHats(vector <int> topHeight, vector <int> topRadius, vector <int> bottomHeight, vector <int> bottomRadius)
-	{
-		int L = topHeight.size();
-		int R = bottomHeight.size();
-		graph G(L+R);
-		for(int i=0; i<L; ++i)
-			for(int k=0; k<R; ++k)
-				if( ok(topHeight[i], topRadius[i], bottomHeight[k], bottomRadius[k]) )
-					G[i].push_back(L+k);
-		return biMatch<100>(G, L);
-	}
-
-	bool ok(int th, int tr, int bh, int br)
-	{
-		if( th*br > bh*tr ) {
-			return br > tr;
-		}
-		return false;
-	}
-};
-
-// BEGIN CUT HERE
-#include <ctime>
-double start_time; string timer()
- { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); }
-template<typename T> ostream& operator<<(ostream& os, const vector<T>& v)
- { os << "{ ";
-   for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it)
-   os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; }
-void verify_case(const int& Expected, const int& Received) {
- bool ok = (Expected == Received);
- if(ok) cerr << "PASSED" << timer() << endl;  else { cerr << "FAILED" << timer() << endl;
- cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } }
-#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock();
-#define END	 verify_case(_, PointyWizardHats().getNumHats(topHeight, topRadius, bottomHeight, bottomRadius));}
-int main(){
-
-CASE(0)
-	int topHeight_[] = {30};
-	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
-	int topRadius_[] = {3};
-	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
-	int bottomHeight_[] = {3};
-	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
-	int bottomRadius_[] = {30};
-	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
-	int _ = 1; 
-END
-CASE(1)
-	int topHeight_[] = {4,4};
-	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
-	int topRadius_[] = {4,3};
-	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
-	int bottomHeight_[] = {5,12};
-	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
-	int bottomRadius_[] = {5,4};
-	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
-	int _ = 1; 
-END
-CASE(2)
-	int topHeight_[] = {3};
-	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
-	int topRadius_[] = {3};
-	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
-	int bottomHeight_[] = {1,1};
-	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
-	int bottomRadius_[] = {2,4};
-	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
-	int _ = 1; 
-END
-CASE(3)
-	int topHeight_[] = {10,10};
-	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
-	int topRadius_[] = {2,5};
-	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
-	int bottomHeight_[] = {2,9};
-	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
-	int bottomRadius_[] = {3,6};
-	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
-	int _ = 2; 
-END
-CASE(4)
-	int topHeight_[] = {3,4,5};
-	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
-	int topRadius_[] = {5,4,3};
-	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
-	int bottomHeight_[] = {3,4,5};
-	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
-	int bottomRadius_[] = {3,8,5};
-	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
-	int _ = 2; 
-END
-CASE(5)
-	int topHeight_[] = {1,2,3,4,5};
-	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
-	int topRadius_[] = {2,3,4,5,6};
-	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
-	int bottomHeight_[] = {2,3,4,5,6};
-	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
-	int bottomRadius_[] = {1,2,3,4,5};
-	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
-	int _ = 0; 
-END
-CASE(6)
-	int topHeight_[] = {123,214,232,323,342,343};
-	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
-	int topRadius_[] = {123,123,232,123,323,434};
-	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
-	int bottomHeight_[] = {545,322,123,545,777,999};
-	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
-	int bottomRadius_[] = {323,443,123,656,767,888};
-	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
-	int _ = 5; 
-END
-CASE(7)
-	int topHeight_[] = {999,999,999,10000,10000,10000};
-	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
-	int topRadius_[] = {10000,10000,10000,1,2,3};
-	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
-	int bottomHeight_[] = {2324,2323,234,5454,323,232};
-	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
-	int bottomRadius_[] = {1,2,3222,434,5454,23};
-	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
-	int _ = 3; 
-END
-/*
-CASE(8)
-	int topHeight_[] = ;
-	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
-	int topRadius_[] = ;
-	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
-	int bottomHeight_[] = ;
-	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
-	int bottomRadius_[] = ;
-	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
-	int _ = ; 
-END
-CASE(9)
-	int topHeight_[] = ;
-	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
-	int topRadius_[] = ;
-	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
-	int bottomHeight_[] = ;
-	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
-	int bottomRadius_[] = ;
-	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
-	int _ = ; 
-END
-*/
-}
-// END CUT HERE

DELETED SRM/549-U/1B.cpp
Index: SRM/549-U/1B.cpp
==================================================================
--- SRM/549-U/1B.cpp
+++ SRM/549-U/1B.cpp
@@ -1,265 +0,0 @@
-#include <iostream>
-#include <sstream>
-#include <iomanip>
-#include <vector>
-#include <string>
-#include <map>
-#include <set>
-#include <algorithm>
-#include <numeric>
-#include <iterator>
-#include <functional>
-#include <complex>
-#include <queue>
-#include <stack>
-#include <cmath>
-#include <cassert>
-using namespace std;
-typedef long long LL;
-typedef long double LD;
-typedef complex<LD> CMP;
-
-class MagicalHats { public:
-	int NC, NH, H, W, NG;
-	vector<int> gain;
-	vector< pair<int,int> > hats;
-	vector<int> tate_base, yoko_base;
-
-	int findMaximumReward(vector <string> board, vector <int> coins, int numGuesses)
-	{
-		NC = coins.size();
-		sort(coins.begin(), coins.end());
-		gain.assign(NC+1, 0);
-		partial_sum(coins.begin(), coins.end(), gain.begin()+1);
-
-		H = board.size();
-		W = board[0].size();
-		hats.clear();
-		tate_base.resize(W);
-		yoko_base.resize(H);
-		for(int y=0; y<H; ++y)
-		for(int x=0; x<W; ++x)
-			if(board[y][x] == 'H') {
-				hats.push_back( make_pair(y,x) );
-				tate_base[x]++;
-				yoko_base[y]++;
-			}
-		NH = hats.size();
-		NG = numGuesses;
-
-		int m = 0;
-		for(int i=0; i<NH; ++i)
-			m = m*3 + 2;
-		p_memo.resize(m+1);
-		p_memo_set.resize(m+1);
-		b_memo.resize(m+1);
-		b_memo_set.resize(m+1);
-		return is_possible(m) ? gain[best_num(m, NG)] : -1;
-	}
-
-	vector<bool> p_memo;
-	vector<bool> p_memo_set;
-	bool is_possible(int state)
-	{
-		if(p_memo_set[state])
-			return p_memo[state];
-		p_memo_set[state] = true;
-
-		vector<int> yoko = yoko_base, tate = tate_base, next;
-		int cnt = 0;
-		for(int i=0,m=1; i<NH; ++i,m*=3)
-		{
-			int v = (state/m)%3;
-			if( v == 1 ) {
-				int y = hats[i].first;
-				int x = hats[i].second;
-				yoko[y]++;
-				tate[x]++;
-				++cnt;
-			} else if( v == 2 ) {
-				next.push_back(m);
-			}
-		}
-		if( next.empty() )
-		{
-			if( cnt != NC )
-				return false;
-			for(int y=0; y<yoko.size(); ++y)
-				if(yoko[y]%2 != 0)
-					return p_memo[state] = false;
-			for(int x=0; x<tate.size(); ++x)
-				if(tate[x]%2 != 0)
-					return p_memo[state] = false;
-			return p_memo[state] = true;
-		}
-		else
-		{
-			int m = next[0];
-			int s[] = {state-2*m, state-m};
-			return p_memo[state] = ( is_possible(s[0]) || is_possible(s[1]) );
-		}
-	}
-
-	vector<char> b_memo;
-	vector<bool> b_memo_set;
-	char best_num(int state, int guess)
-	{
-		if( guess==0 )
-			return 0;
-		if(b_memo_set[state])
-			return b_memo[state];
-		b_memo_set[state] = true;
-
-		char best = 0;
-		for(int i=0,m=1; i<NH; ++i,m*=3)
-		{
-			int v = (state/m)%3;
-			if( v == 2 )
-			{
-				int s[] = {state-2*m, state-m};
-				char score = 13;
-				if( is_possible(s[0]) )
-					score = min(score, best_num(s[0], guess-1));
-				if( is_possible(s[1]) )
-					score = min<char>(score, best_num(s[1], guess-1)+1);
-				best = max(best, score);
-			}
-		}
-		return b_memo[state] = best;
-	}
-};
-
-// BEGIN CUT HERE
-#include <ctime>
-double start_time; string timer()
- { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); }
-template<typename T> ostream& operator<<(ostream& os, const vector<T>& v)
- { os << "{ ";
-   for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it)
-   os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; }
-void verify_case(const int& Expected, const int& Received) {
- bool ok = (Expected == Received);
- if(ok) cerr << "PASSED" << timer() << endl;  else { cerr << "FAILED" << timer() << endl;
- cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } }
-#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock();
-#define END	 verify_case(_, MagicalHats().findMaximumReward(board, coins, numGuesses));}
-int main(){
-
-CASE(0)
-	string board_[] = {"H"};
-	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
-	int coins_[] = {1};
-	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
-	int numGuesses = 1; 
-	int _ = 1; 
-END
-CASE(1)
-	string board_[] = {"HHH",
- "H.H",
- "HH."};
-	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
-	int coins_[] = {9};
-	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
-	int numGuesses = 1; 
-	int _ = 9; 
-END
-CASE(2)
-	string board_[] = {"HH",
- "HH"};
-	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
-	int coins_[] = {1,2,3,4};
-	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
-	int numGuesses = 3; 
-	int _ = 6; 
-END
-CASE(3)
-	string board_[] = {"HHH",
- "HHH",
- "H.H"};
-	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
-	int coins_[] = {13,13,13,13};
-	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
-	int numGuesses = 2; 
-	int _ = 13; 
-END
-CASE(4)
-	string board_[] = {"HHH",
- "HHH",
- "H.H"};
-	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
-	int coins_[] = {13,13,13,13};
-	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
-	int numGuesses = 3; 
-	int _ = 26; 
-END
-CASE(5)
-	string board_[] = {"H.H.",
- ".H.H",
- "H.H."};
-	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
-	int coins_[] = {17};
-	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
-	int numGuesses = 6; 
-	int _ = -1; 
-END
-CASE(6)
-	string board_[] = {"HHH..........",
- "H.H..........",
- "HHH..........",
- "H.H..........",
- "HHH.........."
-".............",
-".............",
-".............",
-".............",
-".............",
-".............",
-".............",
-".............",
-};
-	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
-	int coins_[] = {33,337,1007,2403,5601,6003,9999};
-	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
-	int numGuesses = 5; 
-	int _ = 1377; 
-END
-CASE(7)
-	string board_[] = {".............",
- ".............",
- ".............",
- ".............",
- ".............",
- ".............",
- ".....H.H.....",
- "......H......",
- ".....H.H.....",
- ".............",
- ".............",
- ".............",
- "............."};
-	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
-	int coins_[] = {22};
-	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
-	int numGuesses = 3; 
-	int _ = 22; 
-END
-/*
-CASE(8)
-	string board_[] = ;
-	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
-	int coins_[] = ;
-	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
-	int numGuesses = ; 
-	int _ = ; 
-END
-CASE(9)
-	string board_[] = ;
-	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
-	int coins_[] = ;
-	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
-	int numGuesses = ; 
-	int _ = ; 
-END
-*/
-}
-// END CUT HERE

ADDED   SRM/549/1A.cpp
Index: SRM/549/1A.cpp
==================================================================
--- SRM/549/1A.cpp
+++ SRM/549/1A.cpp
@@ -0,0 +1,204 @@
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <vector>
+#include <string>
+#include <map>
+#include <set>
+#include <algorithm>
+#include <numeric>
+#include <iterator>
+#include <functional>
+#include <complex>
+#include <queue>
+#include <stack>
+#include <cmath>
+#include <cassert>
+using namespace std;
+typedef long long LL;
+typedef long double LD;
+typedef complex<LD> CMP;
+
+typedef int           vert;
+typedef vert          edge;
+typedef vector<edge>  edges;
+typedef vector<edges> graph;
+
+bool augment( graph& G, int v, vector<vert>& matchTo, bool visited[] )
+{
+	for(int i=0; i<G[v].size(); ++i) {
+		vert u = G[v][i];
+		if( visited[u] ) continue;
+		visited[u] = true;
+
+		if( matchTo[u]<0 || augment(G, matchTo[u], matchTo, visited) )
+			{ matchTo[v]=u, matchTo[u]=v; return true; }
+	}
+	return false;
+}
+
+template<int NV>
+int biMatch( graph& G, int L ) // [0,L):left, [L,?):right
+{
+	vector<vert> matchTo(G.size(), -1);
+	int ans = 0;
+	for(vert v=0; v<L; ++v) {
+		bool visited[NV] = {};
+		if( augment(G, v, matchTo, visited) )
+			++ans;
+	}
+	return ans;
+}
+
+class PointyWizardHats { public:
+	int getNumHats(vector <int> topHeight, vector <int> topRadius, vector <int> bottomHeight, vector <int> bottomRadius)
+	{
+		int L = topHeight.size();
+		int R = bottomHeight.size();
+		graph G(L+R);
+		for(int i=0; i<L; ++i)
+			for(int k=0; k<R; ++k)
+				if( ok(topHeight[i], topRadius[i], bottomHeight[k], bottomRadius[k]) )
+					G[i].push_back(L+k);
+		return biMatch<100>(G, L);
+	}
+
+	bool ok(int th, int tr, int bh, int br)
+	{
+		if( th*br > bh*tr ) {
+			return br > tr;
+		}
+		return false;
+	}
+};
+
+// BEGIN CUT HERE
+#include <ctime>
+double start_time; string timer()
+ { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); }
+template<typename T> ostream& operator<<(ostream& os, const vector<T>& v)
+ { os << "{ ";
+   for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it)
+   os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; }
+void verify_case(const int& Expected, const int& Received) {
+ bool ok = (Expected == Received);
+ if(ok) cerr << "PASSED" << timer() << endl;  else { cerr << "FAILED" << timer() << endl;
+ cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } }
+#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock();
+#define END	 verify_case(_, PointyWizardHats().getNumHats(topHeight, topRadius, bottomHeight, bottomRadius));}
+int main(){
+
+CASE(0)
+	int topHeight_[] = {30};
+	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
+	int topRadius_[] = {3};
+	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
+	int bottomHeight_[] = {3};
+	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
+	int bottomRadius_[] = {30};
+	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
+	int _ = 1; 
+END
+CASE(1)
+	int topHeight_[] = {4,4};
+	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
+	int topRadius_[] = {4,3};
+	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
+	int bottomHeight_[] = {5,12};
+	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
+	int bottomRadius_[] = {5,4};
+	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
+	int _ = 1; 
+END
+CASE(2)
+	int topHeight_[] = {3};
+	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
+	int topRadius_[] = {3};
+	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
+	int bottomHeight_[] = {1,1};
+	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
+	int bottomRadius_[] = {2,4};
+	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
+	int _ = 1; 
+END
+CASE(3)
+	int topHeight_[] = {10,10};
+	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
+	int topRadius_[] = {2,5};
+	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
+	int bottomHeight_[] = {2,9};
+	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
+	int bottomRadius_[] = {3,6};
+	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
+	int _ = 2; 
+END
+CASE(4)
+	int topHeight_[] = {3,4,5};
+	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
+	int topRadius_[] = {5,4,3};
+	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
+	int bottomHeight_[] = {3,4,5};
+	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
+	int bottomRadius_[] = {3,8,5};
+	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
+	int _ = 2; 
+END
+CASE(5)
+	int topHeight_[] = {1,2,3,4,5};
+	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
+	int topRadius_[] = {2,3,4,5,6};
+	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
+	int bottomHeight_[] = {2,3,4,5,6};
+	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
+	int bottomRadius_[] = {1,2,3,4,5};
+	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
+	int _ = 0; 
+END
+CASE(6)
+	int topHeight_[] = {123,214,232,323,342,343};
+	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
+	int topRadius_[] = {123,123,232,123,323,434};
+	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
+	int bottomHeight_[] = {545,322,123,545,777,999};
+	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
+	int bottomRadius_[] = {323,443,123,656,767,888};
+	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
+	int _ = 5; 
+END
+CASE(7)
+	int topHeight_[] = {999,999,999,10000,10000,10000};
+	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
+	int topRadius_[] = {10000,10000,10000,1,2,3};
+	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
+	int bottomHeight_[] = {2324,2323,234,5454,323,232};
+	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
+	int bottomRadius_[] = {1,2,3222,434,5454,23};
+	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
+	int _ = 3; 
+END
+/*
+CASE(8)
+	int topHeight_[] = ;
+	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
+	int topRadius_[] = ;
+	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
+	int bottomHeight_[] = ;
+	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
+	int bottomRadius_[] = ;
+	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
+	int _ = ; 
+END
+CASE(9)
+	int topHeight_[] = ;
+	  vector <int> topHeight(topHeight_, topHeight_+sizeof(topHeight_)/sizeof(*topHeight_)); 
+	int topRadius_[] = ;
+	  vector <int> topRadius(topRadius_, topRadius_+sizeof(topRadius_)/sizeof(*topRadius_)); 
+	int bottomHeight_[] = ;
+	  vector <int> bottomHeight(bottomHeight_, bottomHeight_+sizeof(bottomHeight_)/sizeof(*bottomHeight_)); 
+	int bottomRadius_[] = ;
+	  vector <int> bottomRadius(bottomRadius_, bottomRadius_+sizeof(bottomRadius_)/sizeof(*bottomRadius_)); 
+	int _ = ; 
+END
+*/
+}
+// END CUT HERE

ADDED   SRM/549/1B.cpp
Index: SRM/549/1B.cpp
==================================================================
--- SRM/549/1B.cpp
+++ SRM/549/1B.cpp
@@ -0,0 +1,265 @@
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <vector>
+#include <string>
+#include <map>
+#include <set>
+#include <algorithm>
+#include <numeric>
+#include <iterator>
+#include <functional>
+#include <complex>
+#include <queue>
+#include <stack>
+#include <cmath>
+#include <cassert>
+using namespace std;
+typedef long long LL;
+typedef long double LD;
+typedef complex<LD> CMP;
+
+class MagicalHats { public:
+	int NC, NH, H, W, NG;
+	vector<int> gain;
+	vector< pair<int,int> > hats;
+	vector<int> tate_base, yoko_base;
+
+	int findMaximumReward(vector <string> board, vector <int> coins, int numGuesses)
+	{
+		NC = coins.size();
+		sort(coins.begin(), coins.end());
+		gain.assign(NC+1, 0);
+		partial_sum(coins.begin(), coins.end(), gain.begin()+1);
+
+		H = board.size();
+		W = board[0].size();
+		hats.clear();
+		tate_base.resize(W);
+		yoko_base.resize(H);
+		for(int y=0; y<H; ++y)
+		for(int x=0; x<W; ++x)
+			if(board[y][x] == 'H') {
+				hats.push_back( make_pair(y,x) );
+				tate_base[x]++;
+				yoko_base[y]++;
+			}
+		NH = hats.size();
+		NG = numGuesses;
+
+		int m = 0;
+		for(int i=0; i<NH; ++i)
+			m = m*3 + 2;
+		p_memo.resize(m+1);
+		p_memo_set.resize(m+1);
+		b_memo.resize(m+1);
+		b_memo_set.resize(m+1);
+		return is_possible(m) ? gain[best_num(m, NG)] : -1;
+	}
+
+	vector<bool> p_memo;
+	vector<bool> p_memo_set;
+	bool is_possible(int state)
+	{
+		if(p_memo_set[state])
+			return p_memo[state];
+		p_memo_set[state] = true;
+
+		vector<int> yoko = yoko_base, tate = tate_base, next;
+		int cnt = 0;
+		for(int i=0,m=1; i<NH; ++i,m*=3)
+		{
+			int v = (state/m)%3;
+			if( v == 1 ) {
+				int y = hats[i].first;
+				int x = hats[i].second;
+				yoko[y]++;
+				tate[x]++;
+				++cnt;
+			} else if( v == 2 ) {
+				next.push_back(m);
+			}
+		}
+		if( next.empty() )
+		{
+			if( cnt != NC )
+				return false;
+			for(int y=0; y<yoko.size(); ++y)
+				if(yoko[y]%2 != 0)
+					return p_memo[state] = false;
+			for(int x=0; x<tate.size(); ++x)
+				if(tate[x]%2 != 0)
+					return p_memo[state] = false;
+			return p_memo[state] = true;
+		}
+		else
+		{
+			int m = next[0];
+			int s[] = {state-2*m, state-m};
+			return p_memo[state] = ( is_possible(s[0]) || is_possible(s[1]) );
+		}
+	}
+
+	vector<char> b_memo;
+	vector<bool> b_memo_set;
+	char best_num(int state, int guess)
+	{
+		if( guess==0 )
+			return 0;
+		if(b_memo_set[state])
+			return b_memo[state];
+		b_memo_set[state] = true;
+
+		char best = 0;
+		for(int i=0,m=1; i<NH; ++i,m*=3)
+		{
+			int v = (state/m)%3;
+			if( v == 2 )
+			{
+				int s[] = {state-2*m, state-m};
+				char score = 13;
+				if( is_possible(s[0]) )
+					score = min(score, best_num(s[0], guess-1));
+				if( is_possible(s[1]) )
+					score = min<char>(score, best_num(s[1], guess-1)+1);
+				best = max(best, score);
+			}
+		}
+		return b_memo[state] = best;
+	}
+};
+
+// BEGIN CUT HERE
+#include <ctime>
+double start_time; string timer()
+ { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); }
+template<typename T> ostream& operator<<(ostream& os, const vector<T>& v)
+ { os << "{ ";
+   for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it)
+   os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; }
+void verify_case(const int& Expected, const int& Received) {
+ bool ok = (Expected == Received);
+ if(ok) cerr << "PASSED" << timer() << endl;  else { cerr << "FAILED" << timer() << endl;
+ cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } }
+#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock();
+#define END	 verify_case(_, MagicalHats().findMaximumReward(board, coins, numGuesses));}
+int main(){
+
+CASE(0)
+	string board_[] = {"H"};
+	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
+	int coins_[] = {1};
+	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
+	int numGuesses = 1; 
+	int _ = 1; 
+END
+CASE(1)
+	string board_[] = {"HHH",
+ "H.H",
+ "HH."};
+	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
+	int coins_[] = {9};
+	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
+	int numGuesses = 1; 
+	int _ = 9; 
+END
+CASE(2)
+	string board_[] = {"HH",
+ "HH"};
+	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
+	int coins_[] = {1,2,3,4};
+	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
+	int numGuesses = 3; 
+	int _ = 6; 
+END
+CASE(3)
+	string board_[] = {"HHH",
+ "HHH",
+ "H.H"};
+	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
+	int coins_[] = {13,13,13,13};
+	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
+	int numGuesses = 2; 
+	int _ = 13; 
+END
+CASE(4)
+	string board_[] = {"HHH",
+ "HHH",
+ "H.H"};
+	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
+	int coins_[] = {13,13,13,13};
+	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
+	int numGuesses = 3; 
+	int _ = 26; 
+END
+CASE(5)
+	string board_[] = {"H.H.",
+ ".H.H",
+ "H.H."};
+	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
+	int coins_[] = {17};
+	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
+	int numGuesses = 6; 
+	int _ = -1; 
+END
+CASE(6)
+	string board_[] = {"HHH..........",
+ "H.H..........",
+ "HHH..........",
+ "H.H..........",
+ "HHH.........."
+".............",
+".............",
+".............",
+".............",
+".............",
+".............",
+".............",
+".............",
+};
+	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
+	int coins_[] = {33,337,1007,2403,5601,6003,9999};
+	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
+	int numGuesses = 5; 
+	int _ = 1377; 
+END
+CASE(7)
+	string board_[] = {".............",
+ ".............",
+ ".............",
+ ".............",
+ ".............",
+ ".............",
+ ".....H.H.....",
+ "......H......",
+ ".....H.H.....",
+ ".............",
+ ".............",
+ ".............",
+ "............."};
+	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
+	int coins_[] = {22};
+	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
+	int numGuesses = 3; 
+	int _ = 22; 
+END
+/*
+CASE(8)
+	string board_[] = ;
+	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
+	int coins_[] = ;
+	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
+	int numGuesses = ; 
+	int _ = ; 
+END
+CASE(9)
+	string board_[] = ;
+	  vector <string> board(board_, board_+sizeof(board_)/sizeof(*board_)); 
+	int coins_[] = ;
+	  vector <int> coins(coins_, coins_+sizeof(coins_)/sizeof(*coins_)); 
+	int numGuesses = ; 
+	int _ = ; 
+END
+*/
+}
+// END CUT HERE

ADDED   SRM/549/1C.cpp
Index: SRM/549/1C.cpp
==================================================================
--- SRM/549/1C.cpp
+++ SRM/549/1C.cpp
@@ -0,0 +1,317 @@
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <vector>
+#include <string>
+#include <map>
+#include <set>
+#include <algorithm>
+#include <numeric>
+#include <iterator>
+#include <functional>
+#include <complex>
+#include <queue>
+#include <stack>
+#include <cmath>
+#include <cassert>
+using namespace std;
+typedef long long LL;
+typedef long double LD;
+typedef complex<LD> CMP;
+
+template<typename Vert, typename Flow, int NV=16>
+class MaxFlow
+{
+	vector<int> G[NV];
+	Flow F[NV][NV];
+
+public:
+	void addEdge( Vert s, Vert t, Flow f )
+	{
+		G[s].push_back(t);
+		G[t].push_back(s);
+		F[s][t] = f;
+		F[t][s] = 0;
+	}
+
+	Flow calc( Vert S, Vert D )
+	{
+		for( Flow total=0 ;; ) {
+			// Do BFS and compute the level for each node.
+			int LV[NV] = {0};
+			vector<int> Q(1, S);
+			for(int lv=1; !Q.empty(); ++lv) {
+				vector<int> Q2;
+				for(size_t i=0; i!=Q.size(); ++i) {
+					const vector<int>& ne = G[Q[i]];
+					for(size_t j=0; j!=ne.size(); ++j)
+						if( F[Q[i]][ne[j]] && !LV[ne[j]] && ne[j]!=S )
+							LV[ne[j]]=lv, Q2.push_back(ne[j]);
+				}
+				Q.swap(Q2);
+			}
+
+			// Destination is now unreachable. Done.
+			if( !LV[D] )
+				return total;
+
+			// Iterating DFS.
+			bool blocked[NV] = {};
+			total += dinic_dfs( S, D, LV, 0x7fffffff, blocked );
+		}
+	}
+
+private:
+	Flow dinic_dfs( int v, int D, int LV[], Flow flow_in, bool blocked[] )
+	{
+		Flow flow_out = 0;
+		for(size_t i=0; i!=G[v].size(); ++i) {
+			int u = G[v][i];
+			if( LV[v]+1==LV[u] && F[v][u] ) {
+				Flow f = min(flow_in-flow_out, F[v][u]);
+				if( u==D || !blocked[u] && (f=dinic_dfs(u,D,LV,f,blocked))>0 ) {
+					F[v][u]  -= f;
+					F[u][v]  += f;
+					flow_out += f;
+					if( flow_in == flow_out ) return flow_out;
+				}
+			}
+		}
+		blocked[v] = (flow_out==0);
+		return flow_out;
+	}
+};
+
+class CosmicBlocks { public:
+	vector<int> blockTypes;
+	int N, minWays, maxWays;
+
+	int getNumOrders(vector <int> blockTypes_, int minWays_, int maxWays_)
+	{
+		N          = blockTypes_.size();
+		blockTypes = blockTypes_;
+		minWays    = minWays_;
+		maxWays    = maxWays_;
+		return try_all_latitude();
+	}
+
+	int try_all_latitude()
+	{
+		vector<int> lat;
+		return rec_assign_latitude(&lat, (1<<N)-1, 0x7fffffff);
+	}
+
+	int rec_assign_latitude(vector<int>* lat, int mask, int prev_lat_blocks)
+	{
+		if( mask == 0 )
+			return try_all_touching_releation(*lat);
+
+		int total = 0;
+		for(int m=1; m<=mask; ++m) if( (m&mask)==m ) {
+			int sum = 0;
+			for(int i=0; (1<<i)<=m; ++i) if(1<<i & m)
+				sum+=blockTypes[i];
+			if( prev_lat_blocks >= sum ) {
+				lat->push_back(m);
+				total += rec_assign_latitude(lat, mask&~m, sum);
+				lat->pop_back();
+			}
+		}
+		return total;
+	}
+
+	int try_all_touching_releation(const vector<int>& lat)
+	{
+		int total = 0;
+
+		vector<int> fst = elements(lat[0]);
+		vector< pair<int,int> > adj = adjacent_blocks(lat);
+		for(int m=0; m<(1<<adj.size()); ++m)
+		{
+			vector< vector<int> > up(N);
+			up.push_back(fst);
+			for(int i=0; (1<<i)<=m; ++i) if(1<<i & m)
+				up[adj[i].first].push_back(adj[i].second);
+
+			if( !possible(up) )
+				continue;
+			int ways = calc_ways(up);
+			if( minWays<=ways && ways<=maxWays )
+				++total;
+		}
+		return total;
+	}
+
+	vector<int> elements(int mask)
+	{
+		vector<int> result;
+		for(int i=0; (1<<i)<=mask; ++i) if(1<<i & mask)
+			result.push_back(i);
+		return result;
+	}
+
+	vector< pair<int,int> > adjacent_blocks(const vector<int>& lat)
+	{
+		vector< pair<int,int> > result;
+		for(int i=1; i<lat.size(); ++i)
+			for(int a=0; (1<<a)<=lat[i-1]; ++a) if(1<<a & lat[i-1])
+			for(int b=0; (1<<b)<=lat[i];   ++b) if(1<<b & lat[i])
+				result.push_back(make_pair(a,b));
+		return result;
+	}
+
+	int calc_ways(const vector< vector<int> >& up)
+	{
+		vector<int> governed(N);
+		for(int i=0; i<up.size(); ++i)
+			for(int k=0; k<up[i].size(); ++k)
+				governed[up[i][k]] ++;
+
+		// trivial check 2
+		for(int i=0; i<governed.size(); ++i)
+			if(governed[i] == 0)
+				return 0;
+
+		vector<int> memo(1<<N, -1);
+		return calc_ways_rec(N, (1<<N)-1, up, governed, memo);
+	}
+
+	int calc_ways_rec(int i, int mask, const vector< vector<int> >& up, vector<int>& governed,
+		vector<int>& memo)
+	{
+		if(mask == 0)
+			return 1;
+		if(memo[mask] != -1)
+			return memo[mask];
+
+		int sum = 0;
+
+		for(int k=0; k<up[i].size(); ++k) governed[up[i][k]]--;
+		{
+			for(int k=0; k<governed.size(); ++k)
+				if(!governed[k] && (mask & 1<<k))
+					sum += calc_ways_rec(k, mask &~ (1<<k), up, governed, memo);
+		}
+		for(int k=0; k<up[i].size(); ++k) governed[up[i][k]]++;
+
+		return memo[mask] = sum;
+	}
+
+	bool possible(const vector< vector<int> >& up)
+	{
+		static const int INF = 0x3fffffff;
+
+		int total = accumulate(blockTypes.begin(), blockTypes.end(), 0);
+
+		MaxFlow<int, int> mf;
+		vector<int> out = blockTypes, in = blockTypes;
+		for(int v=0; v<=N; ++v) {
+			for(int i=0; i<up[v].size(); ++i) {
+				int u = up[v][i];
+				mf.addEdge(v, N+1+u, INF);
+				if(v<N) {in[v] -= 1; if(in[v]<0) return false; }
+				out[u] -= 1; if(out[u]<0) return false;
+				total -= 1;
+			}
+		}
+		for(int v=0; v<=N; ++v)
+			if(v == N) {
+				mf.addEdge(N+1+N, v, INF);
+			} else {
+				mf.addEdge(N+1+N, v, in[v]);
+				mf.addEdge(N+1+v, N+1+N+1, out[v]);
+			}
+		return mf.calc(N+1+N, N+1+N+1) == total;
+	}
+};
+
+// BEGIN CUT HERE
+#include <ctime>
+double start_time; string timer()
+ { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); }
+template<typename T> ostream& operator<<(ostream& os, const vector<T>& v)
+ { os << "{ ";
+   for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it)
+   os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; }
+void verify_case(const int& Expected, const int& Received) {
+ bool ok = (Expected == Received);
+ if(ok) cerr << "PASSED" << timer() << endl;  else { cerr << "FAILED" << timer() << endl;
+ cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } }
+#define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock();
+#define END	 verify_case(_, CosmicBlocks().getNumOrders(blockTypes, minWays, maxWays));}
+int main(){
+
+CASE(0)
+	int blockTypes_[] = {2,2,2};
+	  vector <int> blockTypes(blockTypes_, blockTypes_+sizeof(blockTypes_)/sizeof(*blockTypes_)); 
+	int minWays = 1; 
+	int maxWays = 1; 
+	int _ = 6; 
+END
+CASE(1)
+	int blockTypes_[] = {1,1,1,1,1,1};
+	  vector <int> blockTypes(blockTypes_, blockTypes_+sizeof(blockTypes_)/sizeof(*blockTypes_)); 
+	int minWays = 720; 
+	int maxWays = 720; 
+	int _ = 1; 
+END
+CASE(2)
+	int blockTypes_[] = {2,2};
+	  vector <int> blockTypes(blockTypes_, blockTypes_+sizeof(blockTypes_)/sizeof(*blockTypes_)); 
+	int minWays = 1; 
+	int maxWays = 2; 
+	int _ = 3; 
+END
+CASE(3)
+	int blockTypes_[] = {1,2};
+	  vector <int> blockTypes(blockTypes_, blockTypes_+sizeof(blockTypes_)/sizeof(*blockTypes_)); 
+	int minWays = 1; 
+	int maxWays = 2; 
+	int _ = 2; 
+END
+CASE(4)
+	int blockTypes_[] = {1};
+	  vector <int> blockTypes(blockTypes_, blockTypes_+sizeof(blockTypes_)/sizeof(*blockTypes_)); 
+	int minWays = 1; 
+	int maxWays = 1; 
+	int _ = 1; 
+END
+CASE(5)
+	int blockTypes_[] = {1,2,4,8};
+	  vector <int> blockTypes(blockTypes_, blockTypes_+sizeof(blockTypes_)/sizeof(*blockTypes_)); 
+	int minWays = 5; 
+	int maxWays = 30; 
+	int _ = 27; 
+END
+CASE(6)
+	int blockTypes_[] = {1,2,3,4,5,6};
+	  vector <int> blockTypes(blockTypes_, blockTypes_+sizeof(blockTypes_)/sizeof(*blockTypes_)); 
+	int minWays = 1; 
+	int maxWays = 720; 
+	int _ = 4445; 
+END
+CASE(7)
+	int blockTypes_[] = {7500,1000,7500,1000,7500};
+	  vector <int> blockTypes(blockTypes_, blockTypes_+sizeof(blockTypes_)/sizeof(*blockTypes_)); 
+	int minWays = 8; 
+	int maxWays = 88; 
+	int _ = 448; 
+END
+/*
+CASE(8)
+	int blockTypes_[] = ;
+	  vector <int> blockTypes(blockTypes_, blockTypes_+sizeof(blockTypes_)/sizeof(*blockTypes_)); 
+	int minWays = ; 
+	int maxWays = ; 
+	int _ = ; 
+END
+CASE(9)
+	int blockTypes_[] = ;
+	  vector <int> blockTypes(blockTypes_, blockTypes_+sizeof(blockTypes_)/sizeof(*blockTypes_)); 
+	int minWays = ; 
+	int maxWays = ; 
+	int _ = ; 
+END
+*/
+}
+// END CUT HERE