题解 [HDU6746] Civilization(贪心+模拟)
一道贪心 + 细节模拟题
题意很简单,这里不详细写了
观察题目,vector
中然后排序,显然在城市分配完毕后,选择权值较大的点作为接下来的工作地点是最优的,接下来模拟每个回合的过程就好了,注意,不需要枚举回合,因为大量相邻的回合所提供的贡献都是相同的,可以将其划分一下,就能快速计算了。
当然这种写法也是时间复杂度挺大的,几乎是卡 3s 通过了
代码
const int N = 5e3 + 10;
int a[N][N];
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int _; for (cin >> _; _--;) {
int n, x, y;
cin >> n >> x >> y;
for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) cin >> a[i][j];
int ans = INT_MAX;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
vectornum;
num.push_back(a[i][j]);
for (int xx = i - 3; xx <= i + 3; xx++)
for (int yy = j - 3; yy <= j + 3; yy++) {
if (xx <= 0 || yy <= 0 || xx > n || yy > n) continue;
if (abs(xx - i) + abs(yy - j) > 3) continue;
if (xx == i && yy == j) continue;
num.push_back(a[xx][yy]);
}
sort(num.begin() + 1, num.end(), greater());
while (num.size() <= 9)
num.push_back(0);
int day = (abs(x - i) + abs(y - j) + 1) / 2; //回合
int sum = 0; //粮食
int t = num[0]; //当前劳动力
for (int i = 1; i <= 8; i++) { //枚举人数
int target = i * i * 8; //需要多少粮食才能升人口
if (sum < target) {
int temp = (target - sum + t - 1) / t; //还需要工作几个回合
sum += temp * t; //加上temp回合的贡献
day += temp; //加上temp回合
}
t += num[i]; //贪心加上新来的人口
}
ans = min(ans, day);
}
cout << ans << "\n";
}
}
分类:
刷题笔记: HDU-OJ
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 分享4款.NET开源、免费、实用的商城系统
· 解决跨域问题的这6种方案,真香!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库
· 5. Nginx 负载均衡配置案例(附有详细截图说明++)
2020-07-30 (转)Github+jsDelivr+PicGo 打造稳定快速、高效免费图床
2020-07-30 解决Github中使用Octotree时,出现 Error: API limit exceeded 报错 或者 Error: Connection error报错的问题(详细操作)
2020-07-30 P3372 【模板】线段树 1
2020-07-30 【题解】Qin Shi Huang's National Road System HDU - 4081 ⭐⭐⭐⭐ 【次小生成树】