40c16bd858 2012-04-11 kinaba: #include <iostream> 40c16bd858 2012-04-11 kinaba: #include <sstream> 40c16bd858 2012-04-11 kinaba: #include <iomanip> 40c16bd858 2012-04-11 kinaba: #include <vector> 40c16bd858 2012-04-11 kinaba: #include <string> 40c16bd858 2012-04-11 kinaba: #include <map> 40c16bd858 2012-04-11 kinaba: #include <set> 40c16bd858 2012-04-11 kinaba: #include <algorithm> 40c16bd858 2012-04-11 kinaba: #include <numeric> 40c16bd858 2012-04-11 kinaba: #include <iterator> 40c16bd858 2012-04-11 kinaba: #include <functional> 40c16bd858 2012-04-11 kinaba: #include <complex> 40c16bd858 2012-04-11 kinaba: #include <queue> 40c16bd858 2012-04-11 kinaba: #include <stack> 40c16bd858 2012-04-11 kinaba: #include <cmath> 40c16bd858 2012-04-11 kinaba: #include <cassert> 40c16bd858 2012-04-11 kinaba: #include <cstring> 40c16bd858 2012-04-11 kinaba: #ifdef __GNUC__ 40c16bd858 2012-04-11 kinaba: #include <ext/hash_map> 40c16bd858 2012-04-11 kinaba: #define unordered_map __gnu_cxx::hash_map 40c16bd858 2012-04-11 kinaba: #else 40c16bd858 2012-04-11 kinaba: #include <unordered_map> 40c16bd858 2012-04-11 kinaba: #endif 40c16bd858 2012-04-11 kinaba: using namespace std; 40c16bd858 2012-04-11 kinaba: typedef long long LL; 40c16bd858 2012-04-11 kinaba: typedef complex<double> CMP; 40c16bd858 2012-04-11 kinaba: 40c16bd858 2012-04-11 kinaba: template<typename T> 40c16bd858 2012-04-11 kinaba: class IdGen 40c16bd858 2012-04-11 kinaba: { 40c16bd858 2012-04-11 kinaba: map<T, int> v2id_; 40c16bd858 2012-04-11 kinaba: vector<T> id2v_; 40c16bd858 2012-04-11 kinaba: public: 40c16bd858 2012-04-11 kinaba: int v2id(const T& v) { 40c16bd858 2012-04-11 kinaba: if( !v2id_.count(v) ) { v2id_[v] = size(); id2v_.push_back(v); } 40c16bd858 2012-04-11 kinaba: return v2id_[v]; 40c16bd858 2012-04-11 kinaba: } 40c16bd858 2012-04-11 kinaba: const T& id2v(int i) const { return id2v_[i]; } 40c16bd858 2012-04-11 kinaba: int size() const { return id2v_.size(); } 40c16bd858 2012-04-11 kinaba: }; 40c16bd858 2012-04-11 kinaba: 40c16bd858 2012-04-11 kinaba: typedef int vert; 40c16bd858 2012-04-11 kinaba: typedef vert edge; 40c16bd858 2012-04-11 kinaba: typedef vector<edge> edges; 40c16bd858 2012-04-11 kinaba: typedef vector<edges> graph; 40c16bd858 2012-04-11 kinaba: 40c16bd858 2012-04-11 kinaba: bool augment( graph& G, int v, vector<vert>& matchTo, bool visited[] ) 40c16bd858 2012-04-11 kinaba: { 40c16bd858 2012-04-11 kinaba: for(int i=0; i<G[v].size(); ++i) { 40c16bd858 2012-04-11 kinaba: vert u = G[v][i]; 40c16bd858 2012-04-11 kinaba: if( visited[u] ) continue; 40c16bd858 2012-04-11 kinaba: visited[u] = true; 40c16bd858 2012-04-11 kinaba: 40c16bd858 2012-04-11 kinaba: if( matchTo[u]<0 || augment(G, matchTo[u], matchTo, visited) ) 40c16bd858 2012-04-11 kinaba: { matchTo[v]=u, matchTo[u]=v; return true; } 40c16bd858 2012-04-11 kinaba: } 40c16bd858 2012-04-11 kinaba: return false; 40c16bd858 2012-04-11 kinaba: } 40c16bd858 2012-04-11 kinaba: 40c16bd858 2012-04-11 kinaba: template<int NV> 40c16bd858 2012-04-11 kinaba: int biMatch( graph& G, int L ) // [0,L):left, [L,?):right 40c16bd858 2012-04-11 kinaba: // only left->right edges are used during computation 40c16bd858 2012-04-11 kinaba: { 40c16bd858 2012-04-11 kinaba: vector<vert> matchTo(G.size(), -1); 40c16bd858 2012-04-11 kinaba: int ans = 0; 40c16bd858 2012-04-11 kinaba: for(vert v=0; v<L; ++v) { 40c16bd858 2012-04-11 kinaba: bool visited[NV] = {}; 40c16bd858 2012-04-11 kinaba: if( augment(G, v, matchTo, visited) ) 40c16bd858 2012-04-11 kinaba: ++ans; 40c16bd858 2012-04-11 kinaba: } 40c16bd858 2012-04-11 kinaba: return ans; 40c16bd858 2012-04-11 kinaba: } 40c16bd858 2012-04-11 kinaba: 40c16bd858 2012-04-11 kinaba: class FoxBomb { public: 40c16bd858 2012-04-11 kinaba: int getMinimumCost(vector <string> grid) 40c16bd858 2012-04-11 kinaba: { 40c16bd858 2012-04-11 kinaba: int H = grid.size(); 40c16bd858 2012-04-11 kinaba: int W = grid[0].size(); 40c16bd858 2012-04-11 kinaba: 40c16bd858 2012-04-11 kinaba: IdGen< pair< int,pair<int,int> > > hline; 40c16bd858 2012-04-11 kinaba: for(int y=0; y<H; ++y) 40c16bd858 2012-04-11 kinaba: for(int sx=0; sx<W; ) 40c16bd858 2012-04-11 kinaba: { 40c16bd858 2012-04-11 kinaba: if( grid[y][sx] == '#' ) 40c16bd858 2012-04-11 kinaba: {++sx; continue;} 40c16bd858 2012-04-11 kinaba: int ex = sx+1; 40c16bd858 2012-04-11 kinaba: for(; ex<W && grid[y][ex]=='.'; ++ex) {} 40c16bd858 2012-04-11 kinaba: if( sx+1 < ex ) 40c16bd858 2012-04-11 kinaba: hline.v2id( make_pair(y, make_pair(sx,ex)) ); 40c16bd858 2012-04-11 kinaba: sx = ex; 40c16bd858 2012-04-11 kinaba: } 40c16bd858 2012-04-11 kinaba: 40c16bd858 2012-04-11 kinaba: IdGen< pair< int,pair<int,int> > > vline; 40c16bd858 2012-04-11 kinaba: for(int x=0; x<W; ++x) 40c16bd858 2012-04-11 kinaba: for(int sy=0; sy<H; ) 40c16bd858 2012-04-11 kinaba: { 40c16bd858 2012-04-11 kinaba: if( grid[sy][x] == '#' ) 40c16bd858 2012-04-11 kinaba: {++sy; continue;} 40c16bd858 2012-04-11 kinaba: int ey = sy+1; 40c16bd858 2012-04-11 kinaba: for(; ey<H && grid[ey][x]=='.'; ++ey) {} 40c16bd858 2012-04-11 kinaba: if( sy+1 < ey ) 40c16bd858 2012-04-11 kinaba: vline.v2id( make_pair(x, make_pair(sy,ey)) ); 40c16bd858 2012-04-11 kinaba: sy = ey; 40c16bd858 2012-04-11 kinaba: } 40c16bd858 2012-04-11 kinaba: 40c16bd858 2012-04-11 kinaba: graph G(hline.size() + vline.size()); 40c16bd858 2012-04-11 kinaba: for(int i=0; i<hline.size(); ++i) 40c16bd858 2012-04-11 kinaba: for(int k=0; k<vline.size(); ++k) 40c16bd858 2012-04-11 kinaba: { 40c16bd858 2012-04-11 kinaba: const pair< int,pair<int,int> >& hh = hline.id2v(i); 40c16bd858 2012-04-11 kinaba: const pair< int,pair<int,int> >& vv = vline.id2v(k); 40c16bd858 2012-04-11 kinaba: int y = hh.first; 40c16bd858 2012-04-11 kinaba: int sx = hh.second.first; 40c16bd858 2012-04-11 kinaba: int ex = hh.second.second; 40c16bd858 2012-04-11 kinaba: int x = vv.first; 40c16bd858 2012-04-11 kinaba: int sy = vv.second.first; 40c16bd858 2012-04-11 kinaba: int ey = vv.second.second; 40c16bd858 2012-04-11 kinaba: if( sx<=x && x<ex && sy<=y && y<ey ) 40c16bd858 2012-04-11 kinaba: G[i].push_back(hline.size()+k); 40c16bd858 2012-04-11 kinaba: } 40c16bd858 2012-04-11 kinaba: 40c16bd858 2012-04-11 kinaba: int dots = 0; 40c16bd858 2012-04-11 kinaba: for(int y=0; y<H; ++y) 40c16bd858 2012-04-11 kinaba: for(int x=0; x<W; ++x) if( grid[y][x]=='.' ) 40c16bd858 2012-04-11 kinaba: { 40c16bd858 2012-04-11 kinaba: int dy[]={-1,+1,0,0}; 40c16bd858 2012-04-11 kinaba: int dx[]={0,0,-1,+1}; 40c16bd858 2012-04-11 kinaba: bool non_wall = false; 40c16bd858 2012-04-11 kinaba: for(int i=0; i<4; ++i) { 40c16bd858 2012-04-11 kinaba: int yy = y+dy[i]; 40c16bd858 2012-04-11 kinaba: int xx = x+dx[i]; 40c16bd858 2012-04-11 kinaba: if(0<=yy&&yy<H&&0<=xx&&xx<W&&grid[yy][xx]=='.') 40c16bd858 2012-04-11 kinaba: non_wall = true; 40c16bd858 2012-04-11 kinaba: } 40c16bd858 2012-04-11 kinaba: if(!non_wall) 40c16bd858 2012-04-11 kinaba: dots++; 40c16bd858 2012-04-11 kinaba: } 40c16bd858 2012-04-11 kinaba: 40c16bd858 2012-04-11 kinaba: return dots + G.size() - biMatch<2500>(G, hline.size()); 40c16bd858 2012-04-11 kinaba: } 40c16bd858 2012-04-11 kinaba: }; 40c16bd858 2012-04-11 kinaba: 40c16bd858 2012-04-11 kinaba: // BEGIN CUT HERE 40c16bd858 2012-04-11 kinaba: #include <ctime> 40c16bd858 2012-04-11 kinaba: double start_time; string timer() 40c16bd858 2012-04-11 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } 40c16bd858 2012-04-11 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) 40c16bd858 2012-04-11 kinaba: { os << "{ "; 40c16bd858 2012-04-11 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) 40c16bd858 2012-04-11 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } 40c16bd858 2012-04-11 kinaba: void verify_case(const int& Expected, const int& Received) { 40c16bd858 2012-04-11 kinaba: bool ok = (Expected == Received); 40c16bd858 2012-04-11 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; 40c16bd858 2012-04-11 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } 40c16bd858 2012-04-11 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); 40c16bd858 2012-04-11 kinaba: #define END verify_case(_, FoxBomb().getMinimumCost(grid));} 40c16bd858 2012-04-11 kinaba: int main(){ 40c16bd858 2012-04-11 kinaba: 40c16bd858 2012-04-11 kinaba: CASE(0) 40c16bd858 2012-04-11 kinaba: string grid_[] = {"#..." 40c16bd858 2012-04-11 kinaba: ,"..##" 40c16bd858 2012-04-11 kinaba: ,"#.##"}; 40c16bd858 2012-04-11 kinaba: vector <string> grid(grid_, grid_+sizeof(grid_)/sizeof(*grid_)); 40c16bd858 2012-04-11 kinaba: int _ = 2; 40c16bd858 2012-04-11 kinaba: END 40c16bd858 2012-04-11 kinaba: CASE(1) 40c16bd858 2012-04-11 kinaba: string grid_[] = {".#.#.#." 40c16bd858 2012-04-11 kinaba: ,"......." 40c16bd858 2012-04-11 kinaba: ,".#.#.#."}; 40c16bd858 2012-04-11 kinaba: vector <string> grid(grid_, grid_+sizeof(grid_)/sizeof(*grid_)); 40c16bd858 2012-04-11 kinaba: int _ = 4; 40c16bd858 2012-04-11 kinaba: END 40c16bd858 2012-04-11 kinaba: CASE(2) 40c16bd858 2012-04-11 kinaba: string grid_[] = {"######################################" 40c16bd858 2012-04-11 kinaba: ,"######################################" 40c16bd858 2012-04-11 kinaba: ,"###.....................##############" 40c16bd858 2012-04-11 kinaba: ,"###.###################.###....#...###" 40c16bd858 2012-04-11 kinaba: ,"###.###################.###.######.###" 40c16bd858 2012-04-11 kinaba: ,"###.###################.###.######.###" 40c16bd858 2012-04-11 kinaba: ,"###.###################.###.######.###" 40c16bd858 2012-04-11 kinaba: ,"###.###################.###.######.###" 40c16bd858 2012-04-11 kinaba: ,"###.###################.###.######.###" 40c16bd858 2012-04-11 kinaba: ,"###.........####........###.######.###" 40c16bd858 2012-04-11 kinaba: ,"###########.###########.###........###" 40c16bd858 2012-04-11 kinaba: ,"###########.###########.##########.###" 40c16bd858 2012-04-11 kinaba: ,"###########.###########.##########.###" 40c16bd858 2012-04-11 kinaba: ,"###########.###########.##########.###" 40c16bd858 2012-04-11 kinaba: ,"###########.###########.##########.###" 40c16bd858 2012-04-11 kinaba: ,"##..........##..........##########.###" 40c16bd858 2012-04-11 kinaba: ,"#######################............###" 40c16bd858 2012-04-11 kinaba: ,"######################################"}; 40c16bd858 2012-04-11 kinaba: vector <string> grid(grid_, grid_+sizeof(grid_)/sizeof(*grid_)); 40c16bd858 2012-04-11 kinaba: int _ = 9; 40c16bd858 2012-04-11 kinaba: END 40c16bd858 2012-04-11 kinaba: CASE(3) 40c16bd858 2012-04-11 kinaba: string grid_[] = {".#." 40c16bd858 2012-04-11 kinaba: ,"..." 40c16bd858 2012-04-11 kinaba: ,"#.#" 40c16bd858 2012-04-11 kinaba: ,"..." 40c16bd858 2012-04-11 kinaba: ,".#."} 40c16bd858 2012-04-11 kinaba: ; 40c16bd858 2012-04-11 kinaba: vector <string> grid(grid_, grid_+sizeof(grid_)/sizeof(*grid_)); 40c16bd858 2012-04-11 kinaba: int _ = 5; 40c16bd858 2012-04-11 kinaba: END 40c16bd858 2012-04-11 kinaba: CASE(4) 40c16bd858 2012-04-11 kinaba: string grid_[] = {"."}; 40c16bd858 2012-04-11 kinaba: vector <string> grid(grid_, grid_+sizeof(grid_)/sizeof(*grid_)); 40c16bd858 2012-04-11 kinaba: int _ = 1; 40c16bd858 2012-04-11 kinaba: END 40c16bd858 2012-04-11 kinaba: CASE(5) 40c16bd858 2012-04-11 kinaba: string grid_[] = {"..."}; 40c16bd858 2012-04-11 kinaba: vector <string> grid(grid_, grid_+sizeof(grid_)/sizeof(*grid_)); 40c16bd858 2012-04-11 kinaba: int _ = 1; 40c16bd858 2012-04-11 kinaba: END 40c16bd858 2012-04-11 kinaba: CASE(6) 40c16bd858 2012-04-11 kinaba: string grid_[] = {".",".","."}; 40c16bd858 2012-04-11 kinaba: vector <string> grid(grid_, grid_+sizeof(grid_)/sizeof(*grid_)); 40c16bd858 2012-04-11 kinaba: int _ = 1; 40c16bd858 2012-04-11 kinaba: END 40c16bd858 2012-04-11 kinaba: CASE(7) 40c16bd858 2012-04-11 kinaba: string grid_[] = { 40c16bd858 2012-04-11 kinaba: "...#.", 40c16bd858 2012-04-11 kinaba: "####.", 40c16bd858 2012-04-11 kinaba: "...#."}; 40c16bd858 2012-04-11 kinaba: vector <string> grid(grid_, grid_+sizeof(grid_)/sizeof(*grid_)); 40c16bd858 2012-04-11 kinaba: int _ = 3; 40c16bd858 2012-04-11 kinaba: END 40c16bd858 2012-04-11 kinaba: } 40c16bd858 2012-04-11 kinaba: // END CUT HERE