提出 #38248714
ソースコード 拡げる
#include <iostream>
#include <vector>
#include <array>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <string>
#include <sstream>
#include <algorithm>
#include <random>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cmath>
#include <cassert>
#include <climits>
#include <bitset>
#include <functional>
#include <iomanip>
#include <random>
#include <optional>
#include <chrono>
#define FOR_LT(i, beg, end) for (std::remove_const<decltype(end)>::type i = beg; i < end; i++)
#define FOR_LE(i, beg, end) for (std::remove_const<decltype(end)>::type i = beg; i <= end; i++)
#define FOR_DW(i, beg, end) for (std::remove_const<decltype(beg)>::type i = beg; end <= i; i--)
#define REP(n) for (std::remove_reference<std::remove_const<decltype(n)>::type>::type repeat_index = 0; repeat_index < n; repeat_index++)
using namespace std;
struct Point {
int x;
int y;
bool operator==(const Point& rhs) const {
return this->x == rhs.x && this->y == rhs.y;
}
bool operator < (const Point& rhs) const {
if (this->x != rhs.x) {
return this->x < rhs.x;
}
return this->y < rhs.y;
}
};
struct PointHash {
size_t operator()(const Point& point) const {
return point.x * 50 + point.y;
}
};
struct Board {
int cell[50][50];
double average_filter(const Point& p) const {
int sum = 0;
int count = 0;
constexpr Point dd[] = { {-1, 0}, {0, -1}, {0, 0}, {0, 1}, {1, 0} };
for (const auto& d : dd) {
const Point& np = { p.x + d.x, p.y + d.y };
if (!this->is_in_board(np)) continue;
sum += cell[np.x][np.y];
count++;
}
return (double)sum / count;
}
int max_filter(const Point& p) const {
int val = 0;
constexpr Point dd[] = { {-1, 0}, {0, -1}, {0, 0}, {0, 1}, {1, 0} };
for (const auto& d : dd) {
const Point& np = { p.x + d.x, p.y + d.y };
if (!this->is_in_board(np)) continue;
val = max(val, cell[np.x][np.y]);
}
return val;
}
static bool is_in_board(const Point& p) {
if (p.x < 0 || 50 <= p.x || p.y < 0 || 50 <= p.y) return false;
return true;
}
};
struct BoardDencity {
int dencity_map[10][10];
int total_dencity = 0;
static const int kAreaSize = 5;
BoardDencity(const Board& board) {
FOR_LT(i, 0, 10) {
FOR_LT(j, 0, 10) {
int xhead = i * 5;
int yhead = j * 5;
int dencity = 0;
FOR_LT(k, 0, kAreaSize) {
FOR_LT(l, 0, kAreaSize) {
int x = xhead + k;
int y = yhead + l;
dencity += board.cell[x][y];
}
}
// cerr << dencity << endl;
this->dencity_map[i][j] = dencity * dencity;
this->total_dencity += dencity * dencity;
}
}
}
Point sum_dencity_to_pos(int sum_dencity) const {
assert(sum_dencity < this->total_dencity);
//std::cerr << sum_dencity << " " << this->total_dencity << endl;
int dencity = 0;
FOR_LT(i, 0, 10) {
FOR_LT(j, 0, 10) {
dencity += this->dencity_map[i][j];
if (sum_dencity < dencity) {
return { i * 5, j * 5 };
}
}
}
assert(false);
return { -1, -1 };
}
};
struct TakenGroup {
unordered_map<Point, int, PointHash> belonging;
unordered_map<int, vector<Point>> belonging_point_list;
unordered_map<int, int> belonging_to_score;
multiset<int> score;
int next_belonging_idx = 0;
int cultivation_count = 0;
};
bool insert_search(const Point& p, int cell_score, int score, bool(&is_used)[50][50], queue<Point>& search) {
if (!Board::is_in_board(p)) return false;
if (is_used[p.x][p.y]) return false;
if (cell_score != score) return false;
is_used[p.x][p.y] = true;
search.push(p);
return true;
}
optional<int> harvest(const Board& board, bool(&is_used)[50][50], const Point& p) {
if (is_used[p.x][p.y]) return std::nullopt;
int score = board.cell[p.x][p.y];
int c = 0;
queue<Point> search;
search.push(p);
c++;
is_used[p.x][p.y] = true;
while (!search.empty()) {
Point cp = search.front();
search.pop();
Point dp[4] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
for (const auto& d : dp) {
Point np = { cp.x + d.x, cp.y + d.y };
if (insert_search(np, board.cell[np.x][np.y], score, is_used, search)) c++;
}
}
if (c < score) return std::nullopt;
return c * board.cell[p.x][p.y];
}
vector<Point> execute_harvest(const Board& board, int max_count) {
bool is_used[50][50] = {};
multimap<int, Point> harvest_list;
FOR_LT(i, 0, 50) {
FOR_LT(j, 0, 50) {
auto harvest_result = harvest(board, is_used, { i, j });
if (harvest_result) {
harvest_list.insert({ harvest_result.value(), {i, j} });
}
}
}
vector<Point> harvest_oplist;
int harvest_count = 0;
for (auto it = harvest_list.rbegin(); it != harvest_list.rend(); it++) {
if (harvest_count == max_count) break;
harvest_oplist.push_back(it->second);
harvest_count++;
}
return harvest_oplist;
}
int evaluate(const Board& board, const Board& culltivation) {
Board value;
int max_count = 2500;
FOR_LT(i, 0, 50) {
FOR_LT(j, 0, 50) {
value.cell[i][j] = board.cell[i][j] + culltivation.cell[i][j];
max_count -= culltivation.cell[i][j];
}
}
if (max_count <= 0) {
return 0;
}
bool is_used[50][50] = {};
multiset<int> harvest_list;
FOR_LT(i, 0, 50) {
FOR_LT(j, 0, 50) {
auto harvest_result = harvest(value, is_used, { i, j });
if (harvest_result) {
harvest_list.insert(harvest_result.value());
}
}
}
int score = 0;
int harvest_count = 0;
for (auto it = harvest_list.rbegin(); it != harvest_list.rend(); it++) {
if (harvest_count == max_count) break;
score += *it;
harvest_count++;
}
return score;
}
vector<Point> conected_point(const Board& board, bool(&is_used)[50][50], const Point& p) {
if (is_used[p.x][p.y]) return {};
vector<Point> connected_point_list;
int score = board.cell[p.x][p.y];
queue<Point> search;
search.push(p);
is_used[p.x][p.y] = true;
connected_point_list.push_back(p);
while (!search.empty()) {
Point cp = search.front();
search.pop();
Point dp[4] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
for (const auto& d : dp) {
Point np = { cp.x + d.x, cp.y + d.y };
if (insert_search(np, board.cell[np.x][np.y], score, is_used, search)) {
connected_point_list.push_back(np);
}
}
}
return connected_point_list;
}
vector<Point> connected_point_with_cultivation(const Board& board, const Board& cultivation, bool(&is_used)[50][50], const Point& p) {
if (is_used[p.x][p.y]) return {};
vector<Point> connected_point_list;
int score = board.cell[p.x][p.y] + cultivation.cell[p.x][p.y];
queue<Point> search;
search.push(p);
is_used[p.x][p.y] = true;
connected_point_list.push_back(p);
while (!search.empty()) {
Point cp = search.front();
search.pop();
Point dp[4] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
for (const auto& d : dp) {
Point np = { cp.x + d.x, cp.y + d.y };
if (insert_search(np, board.cell[np.x][np.y] + cultivation.cell[np.x][np.y], score, is_used, search)) {
connected_point_list.push_back(np);
}
}
}
return connected_point_list;
}
int first_evaluate(const Board& board, TakenGroup& taken_group) {
bool is_used[50][50] = {};
multiset<int> harvest_list;
FOR_LT(i, 0, 50) {
FOR_LT(j, 0, 50) {
auto connected_point_list = conected_point(board, is_used, { i, j });
if (connected_point_list.size() < board.cell[i][j]) continue;
int score = connected_point_list.size() * board.cell[i][j];
for (const auto& point : connected_point_list) {
taken_group.belonging[point] = taken_group.next_belonging_idx;
taken_group.belonging_point_list[taken_group.next_belonging_idx].push_back(point);
}
taken_group.belonging_to_score[taken_group.next_belonging_idx] = score;
taken_group.score.insert(score);
taken_group.next_belonging_idx++;
}
}
int total_score = 0;
for (int score : taken_group.score) {
total_score += score;
}
return total_score;
}
int evaluate_score_set(const multiset<int>& score_set, int max_take_count) {
int take_count = 0;
int total_score = 0;
for (auto it = score_set.rbegin(); it != score_set.rend(); it++) {
if (max_take_count <= take_count) break;
total_score += *it;
take_count++;
}
return total_score;
}
bool is_belonging(const Point& p, const TakenGroup& taken_group) {
if (taken_group.belonging.count(p) == 0) return false;
int belonging = taken_group.belonging.at(p);
if (taken_group.belonging_to_score.count(belonging) == 0) return false;
return true;
}
void insert_delete_belonging_list(const Point& p, const TakenGroup& taken_group, set<int>& delete_belonging_list) {
if (!is_belonging(p, taken_group)) return;
int belonging = taken_group.belonging.at(p);
delete_belonging_list.insert(belonging);
}
int evaluate_in_diff(const Board& board, Board& cultivation, const vector<pair<Point, int>>& diff_list, TakenGroup& taken_group) {
vector<Point> check_point_list;
set<int> delete_belonging_list;
int cultivation_count_diff = 0;
for (const auto& diff : diff_list) {
check_point_list.push_back(diff.first);
cultivation.cell[diff.first.x][diff.first.y] += diff.second;
cultivation_count_diff += diff.second;
insert_delete_belonging_list(diff.first, taken_group, delete_belonging_list);
}
for (int delete_belonging : delete_belonging_list) {
for (const auto& point : taken_group.belonging_point_list.at(delete_belonging)) {
check_point_list.push_back(point);
}
}
bool is_used[50][50] = {};
vector<int> add_score_list;
for (const auto& point : check_point_list) {
insert_delete_belonging_list(point, taken_group, delete_belonging_list);
auto connected_point_list = connected_point_with_cultivation(board, cultivation, is_used, point);
int cell_score = board.cell[point.x][point.y] + cultivation.cell[point.x][point.y];
if (connected_point_list.size() < cell_score) continue;
for (const auto& connected_point : connected_point_list) {
insert_delete_belonging_list(connected_point, taken_group, delete_belonging_list);
}
add_score_list.push_back(cell_score * connected_point_list.size());
}
for (int delete_belonging : delete_belonging_list) {
int score = taken_group.belonging_to_score.at(delete_belonging);
taken_group.score.erase(taken_group.score.find(score));
}
for (int add_score : add_score_list) {
taken_group.score.insert(add_score);
}
int total_score = evaluate_score_set(taken_group.score, 2500 - (taken_group.cultivation_count + cultivation_count_diff));
for (int add_score : add_score_list) {
taken_group.score.erase(taken_group.score.find(add_score));
}
for (int delete_belonging : delete_belonging_list) {
int score = taken_group.belonging_to_score.at(delete_belonging);
taken_group.score.insert(score);
}
for (const auto& diff : diff_list) {
cultivation.cell[diff.first.x][diff.first.y] -= diff.second;
}
return total_score;
}
void update(const Board& board, Board& cultivation, const vector<pair<Point, int>>& diff_list, TakenGroup& taken_group) {
vector<Point> check_point_list;
set<int> delete_belonging_list;
int cultivation_count_diff = 0;
for (const auto& diff : diff_list) {
check_point_list.push_back(diff.first);
cultivation.cell[diff.first.x][diff.first.y] += diff.second;
cultivation_count_diff += diff.second;
insert_delete_belonging_list(diff.first, taken_group, delete_belonging_list);
}
taken_group.cultivation_count += cultivation_count_diff;
for (int delete_belonging : delete_belonging_list) {
for (const auto& point : taken_group.belonging_point_list.at(delete_belonging)) {
check_point_list.push_back(point);
}
}
bool is_used[50][50] = {};
for (const auto point : check_point_list) {
auto connected_point_list = connected_point_with_cultivation(board, cultivation, is_used, point);
int cell_score = board.cell[point.x][point.y] + cultivation.cell[point.x][point.y];
if (connected_point_list.size() < cell_score) continue;
int score = connected_point_list.size() * cell_score;
for (const auto& connected_point : connected_point_list) {
insert_delete_belonging_list(connected_point, taken_group, delete_belonging_list);
taken_group.belonging[connected_point] = taken_group.next_belonging_idx;
taken_group.belonging_point_list[taken_group.next_belonging_idx].push_back(connected_point);
}
taken_group.belonging_to_score[taken_group.next_belonging_idx] = score;
taken_group.score.insert(score);
taken_group.next_belonging_idx++;
}
for (int delete_belonging : delete_belonging_list) {
int score = taken_group.belonging_to_score[delete_belonging];
taken_group.belonging_to_score.erase(delete_belonging);
taken_group.belonging_point_list.erase(delete_belonging);
taken_group.score.erase(taken_group.score.find(score));
}
}
template<typename T> bool has_elem(const vector<T>& vec, const T& elem) {
for (const auto& v : vec) {
if (v == elem) return true;
}
return false;
}
void add_cell(const Point& p, vector<Point>& point_list, vector<Point>& candidate_point_list) {
point_list.push_back(p);
Point dd[4] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
for (const auto& d : dd) {
Point np = { p.x + d.x, p.y + d.y };
if (!Board::is_in_board(np)) continue;
if (has_elem(point_list, np)) continue;
if (has_elem(candidate_point_list, np)) continue;
candidate_point_list.push_back(np);
}
}
vector<pair<Point, int>> random_operation(const Board& board, const Board& cultivation, const BoardDencity& board_dencity, mt19937& rand) {
// uniform_int_distribution<int> area_dist(0, board_dencity.total_dencity - 1);
//auto area_head = board_dencity.sum_dencity_to_pos(area_dist(rand));
//std::cerr << area_idx.first << " " << area_idx.second << endl;
uniform_int_distribution<int> pos_dist(0, 49);
int x = pos_dist(rand);
int y = pos_dist(rand);
//uniform_int_distribution<int> pos_dist(0, BoardDencity::kAreaSize - 1);
//int x = pos_dist(rand) + area_head.x;
//int y = pos_dist(rand) + area_head.y;
// int max_count = ceil(board.average_filter({ x, y }));
//cerr << max_count << " " << board.cell[x][y] << endl;
int kMinCount = 1;
uniform_int_distribution<int> count_dist(kMinCount, board.cell[x][y]);
int point_count = count_dist(rand);
vector<Point> point_list;
{
vector<Point> candidate_point_list;
add_cell({ x, y }, point_list, candidate_point_list);
while (point_list.size() < point_count) {
uniform_int_distribution<int> sel_dist(0, candidate_point_list.size() - 1);
int sel = sel_dist(rand);
Point np = candidate_point_list[sel];
candidate_point_list.erase(candidate_point_list.begin() + sel);
add_cell(np, point_list, candidate_point_list);
}
}
int max_score = 0;
for (const auto& p : point_list) {
max_score = max(max_score, board.cell[p.x][p.y]);
}
vector<pair<Point, int>> diff_list;
for (const auto& p : point_list) {
int diff = max_score - (board.cell[p.x][p.y] + cultivation.cell[p.x][p.y]);
diff_list.push_back({ p, diff });
}
return diff_list;
}
bool is_random_chosen(double temprature, mt19937& rand) {
std::uniform_real_distribution<> dist(0.0, 1.0);
double rand_value = dist(rand);
return rand_value < temprature;
}
void annul_meaningless_cultivation(Board& cultivation, TakenGroup& taken_group) {
FOR_LT(i, 0, 50) {
FOR_LT(j, 0, 50) {
if (taken_group.belonging.count({ i, j }) == 0) {
taken_group.cultivation_count -= cultivation.cell[i][j];
cultivation.cell[i][j] = 0;
continue;
}
int belonging = taken_group.belonging.at({ i, j });
if (taken_group.belonging_to_score.count(belonging) == 0) {
taken_group.cultivation_count -= cultivation.cell[i][j];
cultivation.cell[i][j] = 0;
continue;
}
}
}
}
bool can_remove(const Board& board, Board& cultivation, const Point& p, TakenGroup& taken_group) {
int current_value = board.cell[p.x][p.y] + cultivation.cell[p.x][p.y];
int cultivation_value = cultivation.cell[p.x][p.y];
bool is_used[50][50] = {};
int prev_connected_count = 0;
for (const auto& cp : taken_group.belonging_point_list[taken_group.belonging[p]]) {
if (board.cell[cp.x][cp.y] + cultivation.cell[cp.x][cp.y]) prev_connected_count++;
}
cultivation.cell[p.x][p.y] = 0;
int connected_count = 0;
for (const auto& cp : taken_group.belonging_point_list[taken_group.belonging[p]]) {
if (board.cell[cp.x][cp.y] + cultivation.cell[cp.x][cp.y] != current_value) continue;
auto connected_points = connected_point_with_cultivation(board, cultivation, is_used, cp);
if (connected_points.size() < current_value) continue;
connected_count += connected_points.size();
}
assert(connected_count != prev_connected_count);
cultivation.cell[p.x][p.y] = cultivation_value;
return (connected_count + 1 == prev_connected_count);
}
void easen_cultivation(const Board& board, Board& cultivation, TakenGroup& taken_group) {
array<vector<Point>, 9> value_point_list;
FOR_LT(i, 0, 50) {
FOR_LT(j, 0, 50) {
int value = board.cell[i][j] + cultivation.cell[i][j];
value_point_list[value - 1].push_back({ i, j });
}
}
int reduce_count = 0;
FOR_LT(i, 0, 9) {
int current_value = i + 1;
FOR_LT (pi, 0, value_point_list[i].size()) {
const auto& p = value_point_list[i][pi];
if (current_value != board.cell[p.x][p.y] + cultivation.cell[p.x][p.y]) continue;
if (!is_belonging(p, taken_group)) continue;
constexpr Point dd[4] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
for (const auto& d : dd) {
Point np = { p.x + d.x, p.y + d.y };
if (!Board::is_in_board(np)) continue;
int nvalue = board.cell[np.x][np.y] + cultivation.cell[np.x][np.y];
if (nvalue <= current_value || current_value < board.cell[np.x][np.y]) continue;
if (!is_belonging(np, taken_group)) continue;
if(!can_remove(board, cultivation, np, taken_group)) continue;
cultivation.cell[np.x][np.y] = current_value - board.cell[np.x][np.y];
reduce_count += nvalue - current_value;
value_point_list[i].push_back(np);
}
}
}
// cerr << reduce_count << endl;
Board unified_board;
FOR_LT(i, 0, 50) {
FOR_LT(j, 0, 50) {
unified_board.cell[i][j] = board.cell[i][j] + cultivation.cell[i][j];
}
}
TakenGroup new_taken_group;
int total_value = first_evaluate(unified_board, new_taken_group);
int prev_cultivation_count = taken_group.cultivation_count;
taken_group = std::move(new_taken_group);
taken_group.cultivation_count = prev_cultivation_count - reduce_count;
//cerr << reduce_count << endl;
}
void final_greedy(const Board& board, Board& cultivation, TakenGroup& taken_group) {
auto score_it = taken_group.score.rbegin();
int count_rem = 2500 - taken_group.cultivation_count;
REP(2500 - taken_group.cultivation_count) {
score_it++;
count_rem--;
if (score_it == taken_group.score.rend()) {
break;
}
}
multimap<double, pair<int, Point>> candidate_map;
FOR_LT(i, 0, 50) {
FOR_LT(j, 0, 50) {
if (is_belonging({ i, j }, taken_group)) continue;
constexpr Point dd[4] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
bool found_candidate = false;
int diff = INT_MAX;
for (const auto& d : dd) {
Point np = { i + d.x, j + d.y };
if (!Board::is_in_board(np)) continue;
if (!is_belonging(np, taken_group)) continue;
int ns = board.cell[np.x][np.y] + cultivation.cell[np.x][np.y];
if (board.cell[i][j] < ns) {
found_candidate = true;
int current_diff = ns - board.cell[i][j];
if (current_diff < diff) {
diff = current_diff;
}
}
}
if (found_candidate) {
double ratio = ((double)board.cell[i][j] + diff) / diff;
candidate_map.insert({ ratio, { diff, Point{ i, j } } });
}
}
}
int add_count = 0;
if (count_rem != 0) {
auto cand_it = candidate_map.rbegin();
while (count_rem != 0 && cand_it != candidate_map.rend()) {
const Point& p = cand_it->second.second;
cultivation.cell[p.x][p.y] += cand_it->second.first;
add_count += cand_it->second.first;
count_rem--;
cand_it++;
}
}
else {
int score_diff = 0;
auto cand_it = candidate_map.rbegin();
while (cand_it != candidate_map.rend()) {
const Point& p = cand_it->second.second;
int diff = cand_it->second.first;
int add_score = board.cell[p.x][p.y] + diff;
auto score_it_tmp = score_it;
int org_score = 0;
bool is_ok = true;
REP(diff) {
org_score += *score_it_tmp;
if (score_it_tmp == taken_group.score.rbegin()) {
is_ok = false;
break;
}
score_it_tmp--;
}
if (!is_ok) break;
if (org_score < add_score) {
score_diff += add_score - org_score;
cultivation.cell[p.x][p.y] += diff;
add_count += cand_it->second.first;
if (score_it == taken_group.score.rbegin()) break;
score_it--;
}
cand_it++;
}
// cerr << score_diff << endl;
}
Board unified_board;
FOR_LT(i, 0, 50) {
FOR_LT(j, 0, 50) {
unified_board.cell[i][j] = board.cell[i][j] + cultivation.cell[i][j];
}
}
TakenGroup new_taken_group;
int total_value = first_evaluate(unified_board, new_taken_group);
int prev_cultivation_count = taken_group.cultivation_count;
taken_group = std::move(new_taken_group);
taken_group.cultivation_count = prev_cultivation_count + add_count;
}
void final_choice(const Board& board, Board& cultivation, const TakenGroup& taken_group) {
struct EffectivenessInfo {
int belonging;
int count;
};
multimap<double, EffectivenessInfo> effectiveness_map;
for (const auto& belonging : taken_group.belonging_point_list) {
int cc = 1;
int belonging_id = belonging.first;
for (const auto& p : taken_group.belonging_point_list.at(belonging_id)) {
cc += cultivation.cell[p.x][p.y];
}
double ratio = (double)taken_group.belonging_to_score.at(belonging_id) / cc;
effectiveness_map.insert({ ratio, { belonging_id, cc} });
}
int remain_count = 2500;
vector<int> discard_list;
for (auto it = effectiveness_map.rbegin(); it != effectiveness_map.rend(); it++) {
if (remain_count < it->second.count) {
//std::cerr << "disbel : " << it->second.belonging << " " << it->second.count << " " << taken_group.belonging_to_score.at(it->second.belonging) << endl;
discard_list.push_back(it->second.belonging);
continue;
}
remain_count -= it->second.count;
}
//cerr << "dis : " << discard_list.size() << " " << effectiveness_map.size() << endl;
for (int discord_beloning : discard_list) {
for (const auto& p : taken_group.belonging_point_list.at(discord_beloning)) {
cultivation.cell[p.x][p.y] = 0;
}
}
}
Board annealing(const Board& board) {
auto start_time = chrono::high_resolution_clock::now();
TakenGroup taken_group = {};
int total_score = first_evaluate(board, taken_group);
BoardDencity board_dencity(board);
double temperature = 0.0;
mt19937 rand = mt19937(time(nullptr));
Board cultivation = {};
static int count = 0;
while (true) {
{
auto now = chrono::high_resolution_clock::now();
auto time_diff = now - start_time;
if (chrono::milliseconds(1950) <= time_diff) {
break;
}
}
count++;
auto diff_list = random_operation(board, cultivation, board_dencity, rand);
int next_total_score = evaluate_in_diff(board, cultivation, diff_list, taken_group);
// cerr << total_score << " " << next_total_score << " " << taken_group.cultivation_count << endl;
if (next_total_score == 0) continue;
if (total_score < next_total_score || is_random_chosen(temperature, rand)) {
update(board, cultivation, diff_list, taken_group);
total_score = next_total_score;
}
}
// cerr << count << endl;
annul_meaningless_cultivation(cultivation, taken_group);
easen_cultivation(board, cultivation, taken_group);
final_greedy(board, cultivation, taken_group);
final_choice(board, cultivation, taken_group);
return cultivation;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout << fixed << setprecision(20);
int n, m; cin >> n >> m;
Board board;
FOR_LT(i, 0, 50) {
FOR_LT(j, 0, 50) {
cin >> board.cell[i][j];
}
}
Board cultivation = annealing(board);
int cc = 0;
FOR_LT(i, 0, 50) {
FOR_LT(j, 0, 50) {
cc += cultivation.cell[i][j];
}
}
FOR_LT(i, 0, 50) {
FOR_LT(j, 0, 50) {
board.cell[i][j] += cultivation.cell[i][j];
}
}
auto harvest_points = execute_harvest(board, 2500 - cc);
FOR_LT(i, 0, 50) {
FOR_LT(j, 0, 50) {
REP(cultivation.cell[i][j]) {
cout << 1 << " " << i << " " << j << endl;
}
}
}
for (const auto& point : harvest_points) {
cout << 2 << " " << point.x << " " << point.y << endl;
}
return 0;
}
提出情報
| 提出日時 |
|
| 問題 |
B - ファーマーXの収穫計画 |
| ユーザ |
cplusplusonly |
| 言語 |
C++ (GCC 9.2.1) |
| 得点 |
652081 |
| コード長 |
25188 Byte |
| 結果 |
AC |
| 実行時間 |
1964 ms |
| メモリ |
4200 KiB |
コンパイルエラー
./Main.cpp: In function ‘int first_evaluate(const Board&, TakenGroup&)’:
./Main.cpp:294:36: warning: comparison of integer expressions of different signedness: ‘std::vector<Point>::size_type’ {aka ‘long unsigned int’} and ‘const int’ [-Wsign-compare]
294 | if (connected_point_list.size() < board.cell[i][j]) continue;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
./Main.cpp: In function ‘int evaluate_in_diff(const Board&, Board&, const std::vector<std::pair<Point, int> >&, TakenGroup&)’:
./Main.cpp:366:35: warning: comparison of integer expressions of different signedness: ‘std::vector<Point>::size_type’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
366 | if (connected_point_list.size() < cell_score) continue;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~
./Main.cpp: In function ‘void update(const Board&, Board&, const std::vector<std::pair<Point, int> >&, TakenGroup&)’:
./Main.cpp:422:35: warning: comparison of integer expressions of different signedness: ‘std::vector<Point>::size_type’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
422 | if (connected_point_list.size() < cell_score) continue;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~
./Main.cpp: In function ‘std::vector<std::pair<Point, int> > random_operation(const Board&, const Board&, const BoardDencity&, std::mt19937&)’:
./Main.cpp:487:28: warning: comparison of integer expressions of different signedness: ‘std::vector<Point>::size_type’ {aka ‘long unsigned int’} and ‘int’ [-Wsign-compare]
487 | while (point_list.size() < point_count) {
| ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~
./Main.cpp:465:109: warning: unused parameter ‘board_dencity’ [-Wunused-parameter]
465 | vector<pair<Point, int>> random_operation(const Board& board, const Board& cultivation, const BoardDencity& board_dencity, mt19937& rand) {
| ~~~~~~~~~~~~~~~~~~~...
ジャッジ結果
| セット名 |
test_all |
| 得点 / 配点 |
652081 / 1250000 |
| 結果 |
|
| セット名 |
テストケース |
| test_all |
subtask_01_01.txt, subtask_01_02.txt, subtask_01_03.txt, subtask_01_04.txt, subtask_01_05.txt, subtask_01_06.txt, subtask_01_07.txt, subtask_01_08.txt, subtask_01_09.txt, subtask_01_10.txt, subtask_01_11.txt, subtask_01_12.txt, subtask_01_13.txt, subtask_01_14.txt, subtask_01_15.txt, subtask_01_16.txt, subtask_01_17.txt, subtask_01_18.txt, subtask_01_19.txt, subtask_01_20.txt, subtask_01_21.txt, subtask_01_22.txt, subtask_01_23.txt, subtask_01_24.txt, subtask_01_25.txt, subtask_01_26.txt, subtask_01_27.txt, subtask_01_28.txt, subtask_01_29.txt, subtask_01_30.txt, subtask_01_31.txt, subtask_01_32.txt, subtask_01_33.txt, subtask_01_34.txt, subtask_01_35.txt, subtask_01_36.txt, subtask_01_37.txt, subtask_01_38.txt, subtask_01_39.txt, subtask_01_40.txt, subtask_01_41.txt, subtask_01_42.txt, subtask_01_43.txt, subtask_01_44.txt, subtask_01_45.txt, subtask_01_46.txt, subtask_01_47.txt, subtask_01_48.txt, subtask_01_49.txt, subtask_01_50.txt |
| ケース名 |
結果 |
実行時間 |
メモリ |
| subtask_01_01.txt |
AC |
1964 ms |
4152 KiB |
| subtask_01_02.txt |
AC |
1963 ms |
4152 KiB |
| subtask_01_03.txt |
AC |
1964 ms |
4152 KiB |
| subtask_01_04.txt |
AC |
1964 ms |
4052 KiB |
| subtask_01_05.txt |
AC |
1962 ms |
4180 KiB |
| subtask_01_06.txt |
AC |
1960 ms |
4168 KiB |
| subtask_01_07.txt |
AC |
1963 ms |
4164 KiB |
| subtask_01_08.txt |
AC |
1961 ms |
4104 KiB |
| subtask_01_09.txt |
AC |
1962 ms |
4128 KiB |
| subtask_01_10.txt |
AC |
1960 ms |
4128 KiB |
| subtask_01_11.txt |
AC |
1961 ms |
4200 KiB |
| subtask_01_12.txt |
AC |
1962 ms |
4072 KiB |
| subtask_01_13.txt |
AC |
1961 ms |
4048 KiB |
| subtask_01_14.txt |
AC |
1960 ms |
4116 KiB |
| subtask_01_15.txt |
AC |
1961 ms |
4116 KiB |
| subtask_01_16.txt |
AC |
1961 ms |
4192 KiB |
| subtask_01_17.txt |
AC |
1962 ms |
4148 KiB |
| subtask_01_18.txt |
AC |
1961 ms |
4196 KiB |
| subtask_01_19.txt |
AC |
1960 ms |
4108 KiB |
| subtask_01_20.txt |
AC |
1964 ms |
4136 KiB |
| subtask_01_21.txt |
AC |
1960 ms |
4060 KiB |
| subtask_01_22.txt |
AC |
1960 ms |
4080 KiB |
| subtask_01_23.txt |
AC |
1960 ms |
4056 KiB |
| subtask_01_24.txt |
AC |
1960 ms |
4184 KiB |
| subtask_01_25.txt |
AC |
1963 ms |
4188 KiB |
| subtask_01_26.txt |
AC |
1961 ms |
4156 KiB |
| subtask_01_27.txt |
AC |
1963 ms |
4136 KiB |
| subtask_01_28.txt |
AC |
1961 ms |
4120 KiB |
| subtask_01_29.txt |
AC |
1960 ms |
4160 KiB |
| subtask_01_30.txt |
AC |
1961 ms |
4124 KiB |
| subtask_01_31.txt |
AC |
1961 ms |
4168 KiB |
| subtask_01_32.txt |
AC |
1960 ms |
4112 KiB |
| subtask_01_33.txt |
AC |
1960 ms |
4064 KiB |
| subtask_01_34.txt |
AC |
1960 ms |
4088 KiB |
| subtask_01_35.txt |
AC |
1960 ms |
4044 KiB |
| subtask_01_36.txt |
AC |
1962 ms |
4176 KiB |
| subtask_01_37.txt |
AC |
1960 ms |
4060 KiB |
| subtask_01_38.txt |
AC |
1960 ms |
4156 KiB |
| subtask_01_39.txt |
AC |
1960 ms |
4120 KiB |
| subtask_01_40.txt |
AC |
1960 ms |
4060 KiB |
| subtask_01_41.txt |
AC |
1962 ms |
4172 KiB |
| subtask_01_42.txt |
AC |
1960 ms |
4136 KiB |
| subtask_01_43.txt |
AC |
1961 ms |
4176 KiB |
| subtask_01_44.txt |
AC |
1963 ms |
4112 KiB |
| subtask_01_45.txt |
AC |
1960 ms |
4132 KiB |
| subtask_01_46.txt |
AC |
1960 ms |
4076 KiB |
| subtask_01_47.txt |
AC |
1961 ms |
4076 KiB |
| subtask_01_48.txt |
AC |
1960 ms |
4132 KiB |
| subtask_01_49.txt |
AC |
1960 ms |
4068 KiB |
| subtask_01_50.txt |
AC |
1962 ms |
4012 KiB |