Summer day 11
2016-07-22 13:42
197 查看
今天上午训练赛,没有激情,果断水两道题。
其实每道题都看过,其他题是真不知道算法。等下午讲题后上分析吧。下面是水过的两题。
引用大牛分析。
对于每一只蚂蚁,它在棍子上面,距离左端点和右端点的距离可能是相等的也可能是不同的。暂时把距离远的那端叫做远端,距离近的那端叫做近端。
那么为了使得所有花时间最短,就要让所有的蚂蚁都往近端走,最后总间取决于所有蚂蚁中近端最远的那只蚂蚁,它的时间即是最小时间花费。
同理可推得,要使得所花时间最长,就要让所有蚂蚁都往远端走,这样最后长时间取决于所有蚂蚁中的远端最远的那只蚂蚁。
不用去考虑两只蚂蚁碰头的情况, 因为离远端最远的那只一定是在最右边或者最左边的那只蚂蚁,那么当它往远端方向走时,可能会碰到迎面走来的,那么他马上往回走,对面那只也往回走走,这就相当于“接力”过程,即对面那只蚂蚁替他走这一段本该由他走的路程(整个过程可能会有无数次“接力”,但最终结果都是一样的,只是这段最远路程变成由很多只蚂蚁一起完成)。
以及教训:开数组解决太弱鸡了。读一个处理一个比较高效。
(主要原因是数组开不下= =)
题意:给出长度n和a,b,a,b处有庙,两人轮流重建剩下的位置,直到不能重建为止,每次只能选a+b或者a-b处重建。
分析:若奇异情况(6,8),则其等价于(2,6)(即后者可以生成前者),再推可以得(2);若情况(3,7),等价于(3,4),再等价于(1,3),再等价于(1)。
这正是寻找最大公约数的过程!
gcd(a,b)的倍数即是可以重建的位置,故可以通过n/gcd(a, b)-2的奇偶来判断先手胜负情况。减2是因为已有两座塔a,b。
PS 第二个人叫做Iaka,第一个字母是大写的i,不是小写的L·····mdzz害我WA。
其实每道题都看过,其他题是真不知道算法。等下午讲题后上分析吧。下面是水过的两题。
POJ 1852 Ants (Also UVa 10714)
题意:一根杆上有几个蚂蚁,爬的方向不确定,且两只蚂蚁碰头会反向爬。问所有蚂蚁掉下杆的最短和最长时间。引用大牛分析。
对于每一只蚂蚁,它在棍子上面,距离左端点和右端点的距离可能是相等的也可能是不同的。暂时把距离远的那端叫做远端,距离近的那端叫做近端。
那么为了使得所有花时间最短,就要让所有的蚂蚁都往近端走,最后总间取决于所有蚂蚁中近端最远的那只蚂蚁,它的时间即是最小时间花费。
同理可推得,要使得所花时间最长,就要让所有蚂蚁都往远端走,这样最后长时间取决于所有蚂蚁中的远端最远的那只蚂蚁。
不用去考虑两只蚂蚁碰头的情况, 因为离远端最远的那只一定是在最右边或者最左边的那只蚂蚁,那么当它往远端方向走时,可能会碰到迎面走来的,那么他马上往回走,对面那只也往回走走,这就相当于“接力”过程,即对面那只蚂蚁替他走这一段本该由他走的路程(整个过程可能会有无数次“接力”,但最终结果都是一样的,只是这段最远路程变成由很多只蚂蚁一起完成)。
以及教训:开数组解决太弱鸡了。读一个处理一个比较高效。
(主要原因是数组开不下= =)
#include<iostream> #include<cstdio> #include<cstring> using namespace std; inline int max(int a,int b){ return a>b?a:b; } inline int min(int a,int b){ return a<b?a:b; } int main(){ int nCase, len, n, dist; scanf("%d",&nCase); while(nCase--){ scanf("%d%d",&len, &n); int minLen = -100, maxLen = -100; for(int i=0; i<n; ++i){ scanf("%d",&dist); maxLen = max(maxLen, max(dist, len-dist)); minLen = max(minLen, min(dist, len-dist)); } printf("%d %d\n", minLen, maxLen); } return 0; }
HDU 5512 Pagodas
乍一看博弈论,其实是找规律。题意:给出长度n和a,b,a,b处有庙,两人轮流重建剩下的位置,直到不能重建为止,每次只能选a+b或者a-b处重建。
分析:若奇异情况(6,8),则其等价于(2,6)(即后者可以生成前者),再推可以得(2);若情况(3,7),等价于(3,4),再等价于(1,3),再等价于(1)。
这正是寻找最大公约数的过程!
gcd(a,b)的倍数即是可以重建的位置,故可以通过n/gcd(a, b)-2的奇偶来判断先手胜负情况。减2是因为已有两座塔a,b。
#include<cstdio> int gcd(int a, int b) { if(a%b == 0) return b; else return gcd(b, a%b); } void solve(int n, int a, int b) { int p = gcd(a, b); int avi = n/p -2; if(avi&1) printf("Yuwgna\n"); else printf("Iaka\n"); } int main() { int t, kase = 1; scanf("%d", &t); while(t--) { int n, a, b; scanf("%d%d%d", &n, &a, &b); printf("Case #%d: ",kase++); solve(n, a, b); } return 0; }
PS 第二个人叫做Iaka,第一个字母是大写的i,不是小写的L·····mdzz害我WA。
相关文章推荐
- LeetCode 100. Same Tree
- python-os.walk()使用举例
- ASP.NET CORE 1.0 MVC API 文档用 SWASHBUCKLE SWAGGER实现
- tuple 元组
- 新的博客:http://blog.csdn.net/bat67
- 26个提升java性能需要注意的地方
- linux下网络程序遭遇SIGPIPE信号进程退出的原因及规避方法
- Canvas 学习之 (2) translate
- 使用JavaScript写的一个旋转的彩圈(未测试)
- jquery jsonp 跨域请求
- android平台获取手机IMSI,IMEI ,序列号,和 手机号的方法
- HDU 2157 - How many ways??(矩阵快速幂)
- LeetCode 171. Excel Sheet Column Number
- LeetCode 242. Valid Anagram
- 老程序员十年生涯黯然总结
- BZOJ2342 Manacher + set
- 怎么更改win7登录界面 梦幻桌面动态效果电脑桌面快速分屏设置虚拟wifi热点方法_桌面图标弹出提示飞雪桌面日历自定义桌面
- 性能测试知多少---吞吐量
- 最快让你上手ReactiveCocoa之进阶篇
- vj P1547 逆转,然后再见(记忆化搜索)