CDOJ 28 补兵(kill) 解题报告
2016-07-13 23:33
232 查看
写博客什么的真是……不想动……之前那个没怎么用过的域名已经报废了,今晚倒腾域名折腾了好久。
题目链接http://acm.uestc.edu.cn/#/problem/show/28
一开始我的打算是直接计算出开始和结束的那个点。
既然说了一开始,就说明我失败了……
大概能想到的就是求出每一秒的平均伤害,当然,这对于我的想法并没有什么卯月,只能大致求出一个值,而且我们还不能直接计算出结束点是在我们用平均值计算出来那个点的前面还是后面——可以推算出的就是s肯定在后面,不过我是看了别人的题解后的马后炮。
是的,没错,我去查了题解,看完别人代码后……MDZZ,我居然连暴力都不会打了……
解题方法是先求每一秒的平均值,用这个算出可以开始补兵的时间(我设为s)和应该结束补兵的时间(我设为t),自然,这两个值是不准确的。对于无论是s还是t来说,用每秒平均值计算都可能会出现伤害算多了的情况。我们在得到s和t的近似值之后,向后计算直到s和t均满足各自的要求,也就是对s来说敌军所受的伤害再加上一次自己补兵伤害就会死亡,对于t来说,敌军刚好死亡。
然后再考虑同时攻击的时候己方有人伤害比自己高的情况,这个也是暴力求出。对于每一秒扫一遍,不符合就往中间靠拢。当然,出现s > t的时候就说明不可能存在这个区间,输出Impossible即可。
顺便试试新的代码高亮。
题目链接http://acm.uestc.edu.cn/#/problem/show/28
一开始我的打算是直接计算出开始和结束的那个点。
既然说了一开始,就说明我失败了……
大概能想到的就是求出每一秒的平均伤害,当然,这对于我的想法并没有什么卯月,只能大致求出一个值,而且我们还不能直接计算出结束点是在我们用平均值计算出来那个点的前面还是后面——可以推算出的就是s肯定在后面,不过我是看了别人的题解后的马后炮。
是的,没错,我去查了题解,看完别人代码后……MDZZ,我居然连暴力都不会打了……
解题方法是先求每一秒的平均值,用这个算出可以开始补兵的时间(我设为s)和应该结束补兵的时间(我设为t),自然,这两个值是不准确的。对于无论是s还是t来说,用每秒平均值计算都可能会出现伤害算多了的情况。我们在得到s和t的近似值之后,向后计算直到s和t均满足各自的要求,也就是对s来说敌军所受的伤害再加上一次自己补兵伤害就会死亡,对于t来说,敌军刚好死亡。
然后再考虑同时攻击的时候己方有人伤害比自己高的情况,这个也是暴力求出。对于每一秒扫一遍,不符合就往中间靠拢。当然,出现s > t的时候就说明不可能存在这个区间,输出Impossible即可。
顺便试试新的代码高亮。
#include <cstdio> using namespace std; int N; int A[10005], T[10005]; int P, H; double dmg; int totaldmg; int s, t; int nextInt() { char c; while ((c = getchar()) < '0' || c > '9'); int r = c - '0'; while ((c = getchar()) >= '0' && c <= '9') (r *= 10) += c - '0'; return r; } bool conflict(int time) { for (int i = 1; i < N; ++i) if (!(time % T[i]) && A[i] > P) return true; return false; } int main() { while (N = nextInt()) { dmg = 0; for (int i = 1; i < N; ++i) { A[i] = nextInt(), T[i] = nextInt(); dmg += (double)A[i] / T[i]; } P = nextInt(); H = nextInt(); s = (H - P) / dmg; t = H / dmg; // 暴力扫出起点s totaldmg = 0; for (int i = 1; i < N; ++i) totaldmg += s / T[i] * A[i]; while (totaldmg + P < H) { ++s; for (int i = 1; i < N; ++i) if (!(s % T[i])) totaldmg += A[i]; } while (s <= t && conflict(s)) ++s; // 暴力扫出终点t totaldmg = 0; for (int i = 1; i < N; ++i) totaldmg += t / T[i] * A[i]; while (totaldmg < H) { ++t; for (int i = 1; i < N; ++i) if (!(t % T[i])) totaldmg += A[i]; } while (s <= t && conflict(t)) --t; if (s <= t) printf("%d %d\n", s, t); else puts("Impossible"); } return 0; }
相关文章推荐
- 数据结构の基本概念和术语
- 线程死锁的问题
- 剑指Offer--063-二叉搜索树的第K个结点
- Java并发编程总结2——慎用CAS(转)
- unity模型法线反转问题
- 监控Linux性能的18个命令行工具
- unity3d第三天02(数组)
- Easyui 一些应用
- SSO-C#跨域单点登录(一)
- 想做Android Wear开发?你得先搞明白这四件事
- PhotoShop教程:制作玻璃水晶质感文字
- Linux中的可用内存指的是什么?
- ESP8266 AT指令开发篇(一)
- 巧用ASP.NET中的Web服务器控件
- error LNK2001: unresolved external symbol _IID_ISampleGrabberCB
- mysql优化--博森瑞
- hibernate之关联映射
- MySQL索引原理及慢查询优化
- webpack + vue.js + vue route
- 黑马程序员_Java基础_我的Day26学习笔记