JOI2008-2009をC++で解いてみた4問目
#include <iostream> #include <fstream> #include <vector> #include <string> #include <algorithm> #include <stdlib.h> using namespace std; void outHistory(vector<int>* history_){ vector<int>::iterator iter; for(iter=history_->begin(); history_->end() != iter; iter++){ cout << *iter << "<"; } cout << endl; } class Field{ private: vector<bool> m_fieldline; int m_width, m_height; int m_movement[4]; public: Field(ifstream* ifs){ read(ifs); m_movement[0] = -1; m_movement[1] = -m_width; m_movement[2] = 1; m_movement[3] = m_width; } void read(ifstream* ifs){ string buf; int numline = 0; while(getline(*ifs, buf)){ numline++; if(numline == 1){ m_width = atoi(buf.c_str()); }else if(numline == 2){ m_height = atoi(buf.c_str()); }else{ string::iterator iter; string temp = ""; buf.append(" "); for(iter=buf.begin(); iter != buf.end(); iter++){ if(*iter == ' '){ m_fieldline.push_back(atoi(temp.c_str())); temp.clear(); }else{ temp.append(1, *iter); } } } } } bool operator()(int x_, int y_){ return m_fieldline[y_*m_width + x_]; } const bool operator()(int x_, int y_) const{ return m_fieldline[y_*m_width + x_]; } int start(){ vector<int> steps; vector<int> empty; for(int i=0; i < m_width*m_height; i++){ if(m_fieldline[i] == true){ steps.push_back(walk(i, empty)); } } return *(max_element(steps.begin(), steps.end())); } int walk(int pos, vector<int> history_){ int candidates[4] = {0, 0, 0, 0}; history_.push_back(pos); int invcnt = 0; bool ropes[5]; for(int i=0; i < 4; i++){ candidates[i] = pos + m_movement[i]; ropes[0] = candidates[0]/m_width == pos/m_width; ropes[1] = candidates[2]/m_width == pos/m_width; ropes[2] = !(0 <= candidates[i] and candidates[i] < m_width*m_height); ropes[3] = count(history_.begin(), history_.end(), candidates[i]) != 0; ropes[4] = m_fieldline[candidates[i]] == false; if((i == 0 && ropes[0]) || (i == 2 && ropes[1]) || (i == 1) || (i == 3)){ if(ropes[2] || ropes[3] || ropes[4]){ candidates[i] = -1; //invalid position invcnt++; } }else{ candidates[i] = -1; //invalid position invcnt++; } } outHistory(&history_); if(invcnt == 4){ return history_.size(); }else{ vector<int> steps; for(int i=0; i < 4; i++){ if(candidates[i] != -1){ steps.push_back(walk(candidates[i], history_)); } } return *(max_element(steps.begin(), steps.end())); } return -1; } }; int main(int argc, char* argv[]){ ifstream ifs(argv[1]); Field* f = new Field(&ifs); int result; result = f->start(); cout << result << endl; ofstream ofs(string(string(argv[1]) + string("_out.txt")).c_str()); ofs << result << endl; delete f; f = 0; return 0; }
実行してみるとハカーっぽくて楽しい。まぁごみで実行速度落とすだけだけど。
このくらいになると露骨にPythonとの速度差が出てくる。
SWIG使えばよかったのか?
三問目を飛ばしたのは、かけなかったから。後で書く。