Codeforces Round #124 (Div. 2) 弱菜解题报告
A题一个博弈论的题目,拿过来果断以为奇数1胜,偶数2胜写完提交直接WA....无语。题意是:给定一个n*m的矩形,两人轮往矩形里放半径为r的盘子,盘子必须连接不能覆盖。求谁先胜?
思考,只要第一个人把盘子放在矩形的中心,不论第二个人如何防我只要模仿第二个人怎么放,我肯定能赢。(利用矩形的对称性):
所以代码超简单:
#include <iostream> #include <cstdio> using namespace std; int main() { int a,b,r; scanf("%d%d%d",&a,&b,&r); r = 2*r; if (a < r || b < r) { puts("Second"); } else { puts("First"); } return 0; }
B题是一道纯高数求极限的题目,在求极限那节里老师专门讲过这种“抓大头”的方法,我那节课学的很好,所以肯定会做,TM就是一个小细节让人给查了,汗!
- P(x) = a0·xn + a1·xn - 1 + ... + an - 1·x + an and
- Q(x) = b0·xm + b1·xm - 1 + ... + bm - 1·x + bm.
- Calculate limit .
- 分n == m n > m n < m三种情况讨论即可。就是在n == m时求出最大公约数后,忘了讨论b[0] < 0的情况了,应为输出p/q最间形式并且负号要在p上,所以出错了!
-
#include <iostream> #include <cstdio> #include <cstring> #define maxn 107 using namespace std; int a[maxn],b[maxn]; int gcd(int x,int y) { if (x < y) { int t = x; x = y; y = t; } while (y != 0) { int tmp = y; y = x%y; x = tmp; } return x; } int main() { int n,m,i; while (~scanf("%d%d",&n,&m)) { for (i = 0; i <= n; ++i) scanf("%d",&a[i]); for (i = 0; i <= m; ++i) scanf("%d",&b[i]); if (n == m) { int d = gcd(a[0],b[0]); a[0] = a[0]/d; b[0] = b[0]/d; //注意这一步的判断 if (b[0] < 0) { b[0] = - b[0]; a[0] = - a[0]; } printf("%d/%d",a[0],b[0]); } else if (n > m) { if (a[0]*b[0] > 0) printf("Infinity\n"); else printf("-Infinity\n"); } else { printf("0/1\n"); } } return 0; }
C:果断读错题意:以为求最长上升子序列,果断写了个O(nlogn)的LICS.这里求的是最大子串,不是最长。。。
题意:给定一个字符串s求它的最大子串(子串的下标严格递增的)。
思路:遍历一遍字符串贪心的选择当前最大字符并且该字符在后边的字符串中存在,输出即可。
#include <cstdio> #include <cstring> #include <iostream> #define maxn 100007 using namespace std; char s[maxn]; int L[30]; int main() { int i; scanf("%s",s); int len = strlen(s); memset(L,0,sizeof(L)); for (i = 0; i < len; ++i) L[s[i] - 'a']++;//记录每个字符个数 char ch = 'z'; for (i = 0; i < len; ++i) { while (ch >= 'a' && L[ch - 'a'] == 0) ch--; if (ch < 'a') break; if (s[i] == ch) printf("%c",s[i]); L[s[i] - 'a']--; } return 0; }