結果
問題 | No.20 砂漠のオアシス |
ユーザー | yuma25689 |
提出日時 | 2015-10-31 12:51:15 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 31 ms / 5,000 ms |
コード長 | 7,954 bytes |
コンパイル時間 | 729 ms |
コンパイル使用メモリ | 72,400 KB |
実行使用メモリ | 9,836 KB |
最終ジャッジ日時 | 2024-10-13 05:30:16 |
合計ジャッジ時間 | 1,562 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,816 KB |
testcase_01 | AC | 2 ms
6,820 KB |
testcase_02 | AC | 2 ms
6,820 KB |
testcase_03 | AC | 3 ms
6,816 KB |
testcase_04 | AC | 3 ms
6,816 KB |
testcase_05 | AC | 24 ms
6,856 KB |
testcase_06 | AC | 30 ms
9,836 KB |
testcase_07 | AC | 31 ms
8,428 KB |
testcase_08 | AC | 25 ms
9,448 KB |
testcase_09 | AC | 30 ms
9,580 KB |
testcase_10 | AC | 1 ms
6,816 KB |
testcase_11 | AC | 1 ms
6,816 KB |
testcase_12 | AC | 2 ms
6,824 KB |
testcase_13 | AC | 3 ms
6,816 KB |
testcase_14 | AC | 4 ms
6,820 KB |
testcase_15 | AC | 4 ms
6,816 KB |
testcase_16 | AC | 8 ms
6,820 KB |
testcase_17 | AC | 5 ms
6,820 KB |
testcase_18 | AC | 6 ms
6,820 KB |
testcase_19 | AC | 7 ms
6,816 KB |
testcase_20 | AC | 2 ms
6,816 KB |
ソースコード
#include <iostream> #include <stdlib.h> #include <queue> #include <vector> static const long INF=1e10; class Node { //このdijkstra法で使用するnode int x; int y; long minFromCost; long comeCost; std::vector<long> vToNodeInduces; bool bDone; bool bInQueue; public: class Comparater { public: bool operator() (const Node* n1, const Node* n2) { return (n2->getMinFromCost() < n1->getMinFromCost()); } }; Node(int x,int y, long minFromCost, long comeCost, std::vector<long> vToNodeInduces ) : x(x),y(y),minFromCost(minFromCost),comeCost(comeCost),vToNodeInduces(vToNodeInduces),bDone(false), bInQueue(false) { } void clear() { minFromCost=INF; bDone=false; bInQueue=false; } int getX() { return x; } int getY() { return y; } long getMinFromCost() const { return this->minFromCost; } void setMinFromCost(long minFromCost) { this->minFromCost = minFromCost; } long getComeCost() const { return this->comeCost; } void setComeCost(long comeCost) { this->comeCost = comeCost; } bool isInQueue() const { return bInQueue; } void setInQueue(bool b) { bInQueue=b; } bool isDone() const { return bDone; } void setDone(bool b) { bDone=b; } const std::vector<long>* getToNodeInduces() const { return &vToNodeInduces; } }; typedef std::vector<long>::const_iterator VCL_ITR; typedef std::vector<Node>::iterator VNODE_ITR; void updateCostByDijkstra(Node& firstNode, std::vector<Node>& nodeList)//, std::vector<Node>& targetNodes): { // firstNodeからのnodeList内の全ノードに対して移動するのにかかるコストを取得 // ただし、dijkstra法なので、0<=cost std::priority_queue<Node*,std::vector<Node*>,Node::Comparater> queue; queue.push( &firstNode ); //int count=0; //bool getTarget=false; while( !queue.empty() ) { // キューが空でない限り // キュー取り出し Node* pDoneNode=queue.top(); queue.pop(); pDoneNode->setDone(true); pDoneNode->setInQueue(false); //std::cout << count++ << std::endl; // if targetNodes: // getTarget=True // for t in targetNodes: // if not t.done: // getTarget=False // break // if getTarget: // return for( VCL_ITR itIndex=pDoneNode->getToNodeInduces()->begin(); itIndex != pDoneNode->getToNodeInduces()->end(); ++itIndex ) { if( nodeList[*itIndex].isDone() ) // 確定済みはもう良い?のだろうか? continue; // 接続先ノードを更新 long i=*itIndex; long current = pDoneNode->getMinFromCost() + nodeList[i].getComeCost(); if ( nodeList[i].getMinFromCost() == INF || current < nodeList[i].getMinFromCost() ) { nodeList[i].setMinFromCost( current ); if( nodeList[i].isInQueue() == false ) { nodeList[i].setInQueue(true); queue.push( &nodeList[i] ); // std::cout << "[" << pDoneNode->getX() << "," << pDoneNode->getY() << "]" << "->[" << nodeList[i].getX() << "," << nodeList[i].getY() << "]" << "=" << nodeList[i].getMinFromCost() << "(" << nodeList[i].getComeCost() << ")" << std::endl; } } } } } long glEdgeCount=0; long HP=0; int oasisPos[]={0,0}; long glOasisIndex = -1; int** damageOfPos = NULL; std::vector<Node> vNodes; int main() { std::cin >> glEdgeCount >> HP >> oasisPos[0] >> oasisPos[1]; if( !( oasisPos[0]==0 && oasisPos[1]==0 ) ) { glOasisIndex=oasisPos[1]-1 + (oasisPos[0]-1)*glEdgeCount; } // 二次元配列の使い方がよくわからなくなり、xy逆になってしまった・・・。 damageOfPos = new int*[glEdgeCount]; for( int y=0; y<glEdgeCount; y++) { damageOfPos[y] = new int[glEdgeCount]; for( int x=0; x<glEdgeCount; x++) std::cin >> damageOfPos[y][x]; } // for( int y=0; y<glEdgeCount; y++) // { // std::cout << std::endl; // for( int x=0; x<glEdgeCount; x++) // std::cout << damageOfPos[y][x] << ' '; // } int dx[]={1,0,-1,0}; int dy[]={0,1,0,-1}; for( int x=0; x<glEdgeCount; x++) { for( int y=0; y<glEdgeCount; y++) { std::vector<long> vToNodeInduces; for(int i=0; i < sizeof(dx)/sizeof(int); i++ ) { int nextX = x+dx[i]; int nextY = y+dy[i]; if( ( 0<=nextX && nextX < glEdgeCount ) && ( 0<=nextY && nextY < glEdgeCount ) ) { vToNodeInduces.push_back( nextY + nextX*glEdgeCount ); } } Node node( x, y, INF, damageOfPos[y][x], vToNodeInduces ); vNodes.push_back( node ); } } // 最初の点のコストを0に初期化 vNodes[0].setMinFromCost(0); updateCostByDijkstra(vNodes[0],vNodes); // for( VNODE_ITR itr=vNodes.begin(); itr != vNodes.end(); ++itr ) // std::cout << "[" << itr->getX() << "," << itr->getY() << "]=" << itr->getMinFromCost() << std::endl; if( vNodes.back().getMinFromCost() < HP ) { std::cout << "YES" << std::endl; } else { // HPが足りなかった //std::cout << "HP" << HP << "not enouph.cost" << vNodes.back().getMinFromCost() << std::endl; // オアシス経由でいけるか試す if( glOasisIndex==-1 ) { // オアシスがない // 死亡 // print('not exist oasis') std::cout << "NO" << std::endl; } else { if( vNodes[glOasisIndex].getMinFromCost() < HP ) { // オアシスまではいける // HPをオアシスについた状態から2倍に HP = (HP-vNodes[glOasisIndex].getMinFromCost())*2; // HPが足りなかった //std::cout << "oasis exists [toCost]=" << vNodes[glOasisIndex].getMinFromCost() << std::endl; //std::cout << "HP recovery to " << HP << std::endl; // 最初の点をoasisにしてもう一度dijkstra for( VNODE_ITR itNode = vNodes.begin(); itNode != vNodes.end(); ++itNode ) { itNode->clear(); } vNodes[glOasisIndex].setMinFromCost(0); updateCostByDijkstra(vNodes[glOasisIndex],vNodes); // for node in nodes: // print( "[" + str(node.x) + "," + str(node.y) + "]="+str(node.minFromCost) ) if( vNodes.back().getMinFromCost() < HP ) std::cout << "YES" << std::endl; else std::cout << "NO" << std::endl; } else { // オアシスはあるけど、オアシスにも辿り着けない // アウト // print('cant reach oasis{} HP{}'.format( nodes[oasisIndex].minFromCost, HP)) std::cout << "NO" << std::endl; } } } // メモリ解放 // vectorで良かったのでは・・・ for( int x=0; x<glEdgeCount; x++) delete [] damageOfPos[x]; delete [] damageOfPos; return 0; }