Last active
December 10, 2015 18:35
-
-
Save kngwyu/cdddf406cbf8e2d2ccb9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <cmath> | |
#include <cstring> | |
#include <ctime> | |
#include <iostream> | |
#include <algorithm> | |
#include <set> | |
#include <vector> | |
#include <tuple> | |
#include <sstream> | |
#include <typeinfo> | |
#include <fstream> | |
#include <random> | |
#include <map> | |
using namespace std; | |
//敵の情報を保存するデータ構造 | |
struct Creep { | |
int unique_id; | |
int health; | |
int column; | |
int row; | |
}; | |
//武器となるTowerの情報を保存するデータ構造 | |
struct Tower { | |
int range; | |
int damage; | |
int cost; | |
int numb; | |
}; | |
bool cmp1( const Tower& left, const Tower& right ) { | |
return left.damage == right.damage ? left.cost > right.cost : left.damage > right.damage; | |
} | |
bool cmp2( const Tower& left, const Tower& right ) { | |
return left.range == right.range ? left.cost > right.cost : left.range > right.range; | |
} | |
bool cmp3( const Tower& left, const Tower& right ) { | |
return left.cost == right.cost ? left.range > right.range : left.cost > right.cost; | |
} | |
int main() { | |
int N;// 盤面の1辺の長さ | |
cin >> N; | |
int money;// 所持金 | |
cin >> money; | |
// 盤面の情報を取得する | |
vector<string> board(N); | |
for (int i = 0; i < N; ++i) { | |
cin >> board[i]; | |
} | |
int score[61][61]; | |
for(int i=0;i<N;i++){ | |
for(int j=0;j<N;j++){ | |
score[i][j] = 0; | |
} | |
} | |
int creepHealth; | |
cin >> creepHealth;// Creepの初期体力 | |
int creepMoney; | |
cin >> creepMoney;// Creepを倒すともらえるお金 | |
int M; | |
cin >> M;//Towerの種類 | |
int lcost = 1000000; | |
vector<Tower> towers; | |
for (int i = 0; i < M; ++i) { | |
Tower t; | |
cin >> t.range; | |
cin >> t.damage; | |
cin >> t.cost; | |
t.numb = i; | |
lcost = min(lcost, t.cost); | |
towers.push_back(t); | |
} | |
// ここにTowerを建てたかどうか保存しています | |
vector<vector<bool>> built(N, vector<bool>(N, false)); | |
//縦がi | |
//baseまわりにscoreを足す | |
for(int i=0;i<N;i++){ | |
for(int j=0;j<N;j++){ | |
if(board[i][j] != '.' && board[i][j] != '#'){ | |
for(int k= -5;k<=5;k++){ | |
for(int l= -5;l<=5;l++){ | |
if(i+k < N && j+l < N && i+k >=0 && j+l >= 0 && !(l==0 && k==0)){ | |
if(board[i+k][j+l] == '#'){ | |
if(abs(k)<=3 && abs(l)<=3){ | |
score[i+k][j+l]+= 7; | |
}else{ | |
score[i+k][j+l]+= 5; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
//入り口 | |
for(int i=0;i<N;i++){ | |
if(board[i][0]=='.'){ | |
for(int k= -2;k<=2;k++){ | |
for(int l= 0;l<=2;l++){ | |
if(i+k < N && i+k >= 0 && !(l==0 && k==0)){ | |
if(board[i+k][l] == '#'){ | |
score[i+k][l] += 2; | |
} | |
} | |
} | |
} | |
} | |
if(board[i][N-1]=='.'){ | |
for(int k= -2;k<=2;k++){ | |
for(int l= -3;l<=-1;l++){ | |
if(i+k < N && i+k >= 0 && !(l==0 && k==0)){ | |
if(board[i+k][N+l] == '#'){ | |
score[i+k][N+l] += 2; | |
} | |
} | |
} | |
} | |
} | |
} | |
for(int j=0;j<N;j++){ | |
if(board[0][j]=='.'){ | |
for(int k= -2;k<=2;k++){ | |
for(int l= 0;l<=2;l++){ | |
if(j+k < N && j+k >= 0 && !(l==0 && k==0)){ | |
if(board[l][j+k] == '#'){ | |
score[l][j+k] += 2; | |
} | |
} | |
} | |
} | |
} | |
if(board[N-1][j]=='.'){ | |
for(int k= -2;k<=2;k++){ | |
for(int l= -3;l<=-1;l++){ | |
if(j+k < N && j+k >= 0 && !(l==0 && k==0)){ | |
if(board[l+N][j+k] == '#'){ | |
score[l+N][j+k]+= 2; | |
} | |
} | |
} | |
} | |
} | |
} | |
// Start the Game!! | |
int basehp[61][2001]; | |
for(int i=0;i<61;i++){ | |
for(int j=0;j<2001;j++){ | |
basehp[i][j] = 0; | |
} | |
} | |
for (int turn = 0; turn < 2000; ++turn) { | |
cin >> money; | |
int creepNum; | |
cin >> creepNum;// 盤面上に存在する敵の数 | |
vector<Creep> creeps; | |
for (int i = 0; i < creepNum; ++i) { | |
Creep crp; | |
cin >> crp.unique_id; | |
cin >> crp.health; | |
cin >> crp.column; | |
cin >> crp.row; | |
int j = crp.column;//列 | |
int k = crp.row;//行 | |
for(int l= -2;l<=2;l++){ | |
for(int m= -2;m<=2;m++){ | |
if(j+m < N && k+l < N && j+m >=0 && k+l >= 0 && !(l==0 && m==0) ){ | |
if(board[k+l][j+m] == '#'){ | |
if(abs(l)<=1 && abs(m)<=1){ | |
score[k+l][j+m]+= 2; | |
}else{ | |
score[k+l][j+m]+= 1; | |
} | |
} | |
} | |
} | |
} | |
creeps.push_back(crp); | |
} | |
int baseNum; | |
cin >> baseNum;// Base の数 | |
for (int i = 0; i < baseNum; ++i) { | |
int hp; | |
cin >> hp; | |
basehp[i][turn] = hp; | |
} | |
bool hpkanri = true; | |
if(turn>=300){ | |
for(int i = 0; i < baseNum; i++){ | |
for(int j=1;j<=100;j++){ | |
int k = basehp[i][turn-j] - basehp[i][turn]; | |
if(k!=0){ | |
hpkanri = false; | |
goto KOUGEKI; | |
} | |
} | |
} | |
} | |
KOUGEKI: | |
vector<tuple<int, int, int>> ret;// 出力したい結果をretに保存する | |
// 保存しておいた情報を出力 | |
int nanimosinai = 0; | |
int buildtower=0; | |
if((hpkanri == false && turn>=300) || turn < 300){ | |
while(money>=lcost){ | |
int maxscore=0; | |
int Muki = buildtower%2; | |
int row, column,kind;//builtの初期値はfalse→0 | |
//rowが縦columnが横 | |
if(Muki==0){ | |
for(int i=0;i<N;i++){ | |
for(int j=0;j<N;j++){ | |
if(built[i][j]==false && board[i][j]=='#'){ | |
if(score[i][j] > maxscore){ | |
row = i; | |
column = j; | |
maxscore = score[i][j]; | |
} | |
} | |
} | |
} | |
}else { | |
for(int i=N-1;i>=0;--i){ | |
for(int j=N-1;j>=0;--j){ | |
if(built[i][j]==false && board[i][j]=='#'){ | |
if(score[i][j] > maxscore){ | |
row = i; | |
column = j; | |
maxscore = score[i][j]; | |
} | |
} | |
} | |
} | |
} | |
if(maxscore==0){ | |
break; | |
} | |
built[row][column] = true; | |
if(money>=lcost*2){ | |
if(Muki%2){ | |
//damageが大きい順にsort | |
sort(towers.begin(), towers.end(), cmp1); | |
for(int i=0;i<M;i++){ | |
if(money>=towers[i].cost){ | |
kind = towers[i].numb; | |
money = money - towers[i].cost; | |
break; | |
} | |
} | |
}else{ | |
//rangeが大きい順にsort | |
sort(towers.begin(), towers.end(), cmp2); | |
for(int i=0;i<M;i++){ | |
if(money>=towers[i].cost){ | |
kind = towers[i].numb; | |
money = money - towers[i].cost; | |
break; | |
} | |
} | |
} | |
}else{ | |
//安い順にsort | |
sort(towers.begin(), towers.end(), cmp3); | |
for(int i=0;i<M;i++){ | |
if(money>=towers[i].cost){ | |
kind = towers[i].numb; | |
money = money - towers[i].cost; | |
break; | |
} | |
} | |
} | |
ret.push_back(make_tuple(column, row, kind)); | |
built[row][column] = true; | |
nanimosinai += 1; | |
buildtower +=1; | |
} | |
} | |
if(nanimosinai==0){ | |
cout << "-1" << endl; | |
}else{ | |
cout << ret.size() << endl; | |
for (int i = 0; i < ret.size(); ++i) { | |
cout << get<0>(ret[i]) << " " << get<1>(ret[i]) << " " << get<2>(ret[i]) | |
<< endl; | |
} | |
} | |
} | |
} | |
//java PathDefenseVis -exec "./AIver2" -seed 29 -novis | |
//g++ -std=c++11 PathDefenseKai.cpp -o AIver2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment