BestCoder Round #36 HDU(5198 - 5201)
来源:互联网 发布:课程录制软件 编辑:程序博客网 时间:2024/05/20 20:18
人生第一次ak了bc, 当然要写个题解装逼一下。。(其实是题水。。。)
Hdu 5198 Strang Class
水题。。 不过wa了两发。。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <vector>#include <set>#include <map>using namespace std;#define mxn 100020#define LL long long#define inf 0x3f3f3f3f#define MP make_pairchar s[mxn];int n;bool check(int l, int r) { for(int i = l; i <= r; ++i) if(s[i] != s[l]) return 0; return 1;}int main() { while(scanf("%s", s + 1) != EOF) { n = strlen(s + 1); if(n % 3 != 0) { puts("NO"); continue; } int x = n / 3 + 1; int y = n / 3 * 2 + 1; int z = n / 3; if(check(1, 1 + z - 1) && check(x, x + z - 1) && check(y, y + z - 1)) { if(s[1] != s[x] && s[1] != s[y] && s[x] != s[y]) puts("YES"); else puts("NO"); } else puts("NO"); } return 0;}
Hdu 5199 Gunner
也是水题, 离散化一下, 再加个输入挂就ok了
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <vector>#include <set>#include <map>using namespace std;#define mxn 1000200#define LL long long#define inf 0x3f3f3f3f#define MP make_pairint n, m;int a[mxn];int readint() { char c; while((c = getchar()) && !(c >= '0' && c <= '9')); int ret = c - '0'; while((c = getchar()) && (c >= '0' && c <= '9')) ret = ret * 10 + c - '0'; return ret;}int san[mxn], cnt;bool vis[mxn];int f(int v) { int k = lower_bound(a + 1, a + n + 1, v) - a; if(k > n || a[k] != v) return 0; return 1;}int main() { while(scanf("%d%d", &n, &m) != EOF) { for(int i = 1; i <= n; ++i) a[i] = readint(); memset(vis, 0, sizeof vis); sort(a + 1, a + n + 1); while(m--) { int v; v = readint(); if(f(v) == 0) { puts("0"); continue; } int p = lower_bound(a + 1, a + n + 1, v) - a; if(vis[p]) { puts("0"); continue; } else { int y = upper_bound(a + 1, a + n + 1, v) - a; vis[p] = 1; printf("%d\n", y - p); } } } return 0;}
Hdu 5200 Trees
题意:
给n个数, 树高为hi, q次询问, 每次询问把小于等于v的树都去掉, 剩下的树分成了几块。
思路:
正向处理的话用线段树是比较麻烦的, 但是如果离线的话, 按照询问从小到达来处理就比较容易。
把一个树去掉的话, 如果它的旁边没有树的话, 分块数要减少1, 如果有两棵树的话, 分块数加1, 否则不变。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <vector>#include <set>#include <map>using namespace std;#define mxn 50020#define LL long long#define inf 0x3f3f3f3f#define MP make_pair#define ls (i << 1)#define rs (ls | 1)#define md ((ll + rr) >> 1)struct query { int x, id, ans; bool operator < (const query &b) const { return x < b.x; }}s[mxn];bool cmp(query a, query b) { return a.id < b.id;}int n, q;struct node { int h, p; bool operator < (const node &b) const { return h < b.h; }}a[mxn];bool c[mxn];int main() { while(scanf("%d%d", &n, &q) != EOF) { for(int i = 1; i <= n; ++i) { scanf("%d", &a[i].h); a[i].p = i; } sort(a + 1, a + n + 1); for(int i = 1; i <= q; ++i) { scanf("%d", &s[i].x); s[i].id = i; } sort(s + 1, s + q + 1); int ans = 1; memset(c, true, sizeof c); int j = 1; for(int i = 1; i <= q; ++i) { while(j <= n && a[j].h <= s[i].x) { int h = a[j].p; int cnt = 0; if(h > 1 && c[h-1]) ++cnt; if(h < n && c[h+1]) ++cnt; if(cnt == 2) ++ans; else if(cnt == 0) --ans; c[h] = 0; ++j; } s[i].ans = ans; } sort(s + 1, s + q + 1, cmp); for(int i = 1; i <= q; ++i) printf("%d\n", s[i].ans); } return 0;}
Hdu 5201 The Monkey King
题意:
要把n个桃子分给m个猴子, 其中第一个猴子的桃子要严格最多的, 问方案数。
思路:
可以枚举分多少个桃子给第一个猴子, 假设为x, 那么分给其他猴子的桃子假设为a[i], 那么
a[2] + a[3] + ... + a[m-1] = n - x, 如果没有限制的话, 答案就是f(n-x, m-1), f(x, y) 表示把x个桃子分给y个猴子的方案,显然f(x, y) = C(x + y - 1, x), C是组合数。
有限制的话, 可以根据容斥, 算出总的,然后减去1个猴子比第一个猴子的桃子多的方案,然后加上2个猴子比第一个猴子多的方案。。。
k个猴子比第一个猴子多的方案是C(m-1, k) * f(n - (k + 1) * x, m - 1)。
然后加起来就可以了。
刚开始sb了, 以为这么算复杂度是n^2。
其实每个x, 都是只有O(n/x)次计算的, 因为n - (k + 1) * x < 0时候就跳出循环, 所以复杂度和筛法那样。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <vector>#include <set>#include <map>using namespace std;#define mxn 200020#define LL long long#define inf 0x3f3f3f3f#define MP make_pair#define ls (i << 1)#define rs (ls | 1)#define md ((ll + rr) >> 1)#define mod 1000000007LL fac[mxn], nfac[mxn];LL qpow(LL x, int k) { LL ret = 1; while(k) { if(k & 1) ret = ret * x % mod; x = x * x % mod; k >>= 1; } return ret;}void init() { fac[0] = fac[1] = nfac[0] = nfac[1] = 1; for(int i = 2; i < mxn; ++i) { fac[i] = fac[i-1] * i % mod; nfac[i] = qpow(fac[i], mod - 2); }}int n, m;LL C(int x, int y) { if(y < 0 || y > x) return 0; return fac[x] * nfac[y] % mod * nfac[x-y] % mod;}LL f(int r, int k) { return C(r + k - 1, r);}LL calc(LL x) { LL ret = 0; for(int k = 0; (k + 1) * x <= n; ++k) { LL t = C(m - 1, k) * f(n - (k + 1) * x, m - 1) % mod; if(k & 1) ret = ((ret - t) % mod + mod) % mod; else ret = (ret + t) % mod; } return ret;}int main() { init(); int cas; scanf("%d", &cas); while(cas--) { scanf("%d%d", &n, &m); if(m == 1) { printf("%d\n", 1); continue; } int t = n / m; if(n % m == 0) ++t; else if(n % m != 1) t += 2; LL ans = 0; for(int i = max(1, t); i <= n; ++i) { ans = (ans + calc(i)) % mod; } printf("%I64d\n", ans); } return 0;}
0 0
- BestCoder Round #36 HDU(5198 - 5201)
- hdu 5201 The Monkey King && BestCoder Round #36
- BestCoder Round #36 HDU 5199 Gunner
- HDU BestCoder Round #48 1001
- hdu 5641 BestCoder Round #75
- hdu 5643 BestCoder Round #75
- BestCoder Round #83(HDU 5680)
- [BestCoder] Round #36
- BestCoder Round #36
- BestCoder Round #48 ($) (hdu 5284、hdu 5285)
- [BestCoder Round #3] hdu 4908 BestCoder Sequence (计数)
- hdu 4908 BestCoder Sequence && BestCoder Round #3 1002
- HDU 4908 BestCoder Sequence——BestCoder Round #3
- HDU BestCoder Round #1 1002 项目管理
- BestCoder round#3 1001 && Hdu 4907
- HDU 4907 Task schedule(BestCoder Round #3 )
- hdu 4989 Summary(BestCoder Round #8 1001)
- 【HDU】BestCoder Round #11 (Div. 2)
- AndroidStudio常用快捷键
- 计算智能---绪论
- 基于C#的socket编程的TCP同步实现
- runtime 由浅入深
- 解决 “无法安装 Visual Studio 2010 Service Pack 1,因为此计算机的状态不支持
- BestCoder Round #36 HDU(5198 - 5201)
- 从头到尾彻底解析Hash表算法 - fff8965
- 手把手教你:解决django关于图片无法显示的问题
- C++找对象的季节——指向学生类的指针
- Nomial
- 合理使用导出csv、excel方式
- 三个强攻信号 节后大涨无悬念
- Tableau Desktop(二)
- awk介绍