【玩耍】一水
来源:互联网 发布:淘宝日本代购店铺推荐 编辑:程序博客网 时间:2024/04/29 15:31
【训练赛地址】点击打开链接
【PS】由于几乎是中文题目和题目比较短,就不说题意了。
【A】中文题目,状压+BFS,没有什么坑点,上代码。
【AC代码】
////Created by just_sort 2016/12/1//Copyright (c) 2016 just_sort.All Rights Reserved//#include <ext/pb_ds/assoc_container.hpp>#include <ext/pb_ds/tree_policy.hpp>#include <ext/pb_ds/hash_policy.hpp>#include <set>#include <map>#include <queue>#include <stack>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;using namespace __gnu_pbds;typedef long long LL;typedef pair<int, LL> pp;#define MP(x,y) make_pair(x,y)const int maxn = 200005;typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>order_set;//headint n, m, tt, sx, sy;int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};char maze[22][22];bool vis[22][22][1<<10];struct node{ int x, y, t, state; node(){} node(int x, int y, int t, int state):x(x), y(y), t(t), state(state){}};int getid(char c){ if(islower(c)){ return c - 'a'; } else{ return c - 'A'; }}int bfs(){ queue<node>q; node now, nex; now = node(sx, sy, 0, 0); q.push(now); vis[sx][sy][0] = 1; while(!q.empty()){ now = q.front(); q.pop(); if(now.t >= tt) break; for(int i = 0; i < 4; i++){ int dx = now.x + dir[i][0]; int dy = now.y + dir[i][1]; int t = now.t + 1; int state = now.state; if(vis[dx][dy][state] || dx < 0 || dx >= n || dy < 0 || dy >= m || maze[dx][dy] == '*'){ continue; } if(isupper(maze[dx][dy]) && !(state & (1<<getid(maze[dx][dy])))) continue; if(islower(maze[dx][dy])) state |= (1<<getid(maze[dx][dy])); if(maze[dx][dy] == '^') return t; if(!vis[dx][dy][state]){ vis[dx][dy][state] = 1; q.push(node(dx, dy, t, state)); } } } return -1;}int main(){ while(scanf("%d%d%d",&n,&m,&tt)!=EOF) { tt -= 1; memset(vis, false, sizeof(vis)); for(int i = 0; i < n; i++) scanf("%s", maze[i]); for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ if(maze[i][j] == '@'){ sx = i, sy = j, maze[i][j] = '.'; break; } } } int ans = bfs(); printf("%d\n",ans); } return 0;}
【B】先考虑每一行,再考虑一下每一行里面的元素,发现解决的这个问题有大量的重叠子问题,一个简单的dp想法就由然而生了。
【代码君】
////Created by just_sort 2016/12/1//Copyright (c) 2016 just_sort.All Rights Reserved//#include <ext/pb_ds/assoc_container.hpp>#include <ext/pb_ds/tree_policy.hpp>#include <ext/pb_ds/hash_policy.hpp>#include <set>#include <map>#include <queue>#include <stack>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;using namespace __gnu_pbds;typedef long long LL;typedef pair<int, LL> pp;#define MP(x,y) make_pair(x,y)const int maxn = 200005;typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>order_set;//headint dp1[maxn], dp2[maxn];int n, m;int main(){ while(scanf("%d%d",&n,&m)!=EOF) { memset(dp1, 0, sizeof(dp1)); memset(dp2, 0, sizeof(dp2)); for(int i = 2; i <= n + 1; i++){ for(int j = 2; j <= m + 1; j++){ int x; scanf("%d", &x); dp1[j] = max(dp1[j-1], dp1[j-2]+x); } dp2[i] = max(dp2[i-1], dp2[i-2] + dp1[m + 1]); } printf("%d\n", dp2[n+1]); } return 0;}
【C】就是线段树的区间合并问题,不过这个题要维护的东西有点多,看代码吧。
////Created by just_sort 2016/12/1//Copyright (c) 2016 just_sort.All Rights Reserved////#include <ext/pb_ds/assoc_container.hpp>//#include <ext/pb_ds/tree_policy.hpp>//#include <ext/pb_ds/hash_policy.hpp>//#include <set>//#include <map>//#include <queue>//#include <stack>//#include <cmath>//#include <cstdio>//#include <cstdlib>//#include <cstring>//#include <iostream>//#include <algorithm>//using namespace std;//using namespace __gnu_pbds;//typedef long long LL;//typedef pair<int, LL> pp;//#define MP(x,y) make_pair(x,y)const int maxn = 200005;//typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>order_set;//head#include <cstdio>#include <iostream>#include <algorithm>using namespace std;struct node{ int l, r, len; int l0, l1;//左端点开始的0,1的个数 int r0, r1;//右端点开始的0,1的个数 int max0, max1, cnt0, cnt1, flag;//区间连续0,1的个数,区间0,1的个数}Tree[maxn<<2];int n, m, A[maxn];void pushup(int rt){ Tree[rt].l0 = Tree[rt*2].l0; if(Tree[rt*2].l0 == Tree[rt*2].len) Tree[rt].l0 += Tree[rt*2+1].l0; Tree[rt].r0 = Tree[rt*2+1].r0; if(Tree[rt*2+1].r0 == Tree[rt*2+1].len) Tree[rt].r0 += Tree[rt*2].r0; Tree[rt].max0 = max(Tree[rt*2].max0, Tree[rt*2+1].max0); Tree[rt].max0 = max(Tree[rt].max0, Tree[rt*2].r0 + Tree[rt*2+1].l0); Tree[rt].cnt0 = Tree[rt*2].cnt0 + Tree[rt*2+1].cnt0; Tree[rt].l1 = Tree[rt*2].l1; if(Tree[rt*2].l1 == Tree[rt*2].len) Tree[rt].l1 += Tree[rt*2+1].l1; Tree[rt].r1 = Tree[rt*2+1].r1; if(Tree[rt*2+1].r1 == Tree[rt*2+1].len) Tree[rt].r1 += Tree[rt*2].r1; Tree[rt].max1 = max(Tree[rt*2].max1, Tree[rt*2+1].max1); Tree[rt].max1 = max(Tree[rt].max1, Tree[rt*2].r1 + Tree[rt*2+1].l1); Tree[rt].cnt1 = Tree[rt*2].cnt1 + Tree[rt*2+1].cnt1; //Tree[rt].len = Tree[rt*2].len + Tree[rt*2+1].len;}void Build(int l, int r, int rt){ Tree[rt].l = l, Tree[rt].r = r, Tree[rt].len = r - l + 1, Tree[rt].flag = -1; if(l == r){ Tree[rt].l0 = Tree[rt].r0 = Tree[rt].max0 = Tree[rt].cnt0 = !A[l]; Tree[rt].l1 = Tree[rt].r1 = Tree[rt].max1 = Tree[rt].cnt1 = A[l]; return ; } int mid = (l + r) / 2; Build(l, mid, rt*2); Build(mid+1, r, rt*2+1); pushup(rt);}void update(int L, int R, int rt, int cmd){ if(Tree[rt].l == L && Tree[rt].r == R){ if(cmd == 0) { Tree[rt].l0 = Tree[rt].r0 = Tree[rt].max0 = Tree[rt].cnt0 = Tree[rt].len; Tree[rt].l1 = Tree[rt].r1 = Tree[rt].max1 = Tree[rt].cnt1 = 0; Tree[rt].flag = 0; } else if(cmd == 1){ Tree[rt].l0 = Tree[rt].r0 = Tree[rt].max0 = Tree[rt].cnt0 = 0; Tree[rt].l1 = Tree[rt].r1 = Tree[rt].max1 = Tree[rt].cnt1 = Tree[rt].len; Tree[rt].flag = 1; } else if(cmd == 2){ swap(Tree[rt].l0, Tree[rt].l1); swap(Tree[rt].r0, Tree[rt].r1); swap(Tree[rt].max0, Tree[rt].max1); swap(Tree[rt].cnt0, Tree[rt].cnt1); Tree[rt].flag = 1 - Tree[rt].flag; } return ; } //lazy 操作 if(Tree[rt].flag >= 0){ update(Tree[rt*2].l, Tree[rt*2].r, rt*2, Tree[rt].flag); update(Tree[rt*2+1].l, Tree[rt*2+1].r, rt*2+1, Tree[rt].flag); Tree[rt].flag = -1; } int mid = (Tree[rt].l + Tree[rt].r) / 2; if(R <= mid) update(L, R, rt*2, cmd); else if(L > mid) update(L, R, rt*2+1, cmd); else { update(L, mid, rt*2, cmd); update(mid+1, R, rt*2+1, cmd); } pushup(rt);}node query(int L, int R, int rt){ if(L == Tree[rt].l && Tree[rt].r == R) return Tree[rt]; //lazy 操作 if(Tree[rt].flag >= 0){ update(Tree[rt*2].l, Tree[rt*2].r, rt*2, Tree[rt].flag); update(Tree[rt*2+1].l, Tree[rt*2+1].r, rt*2+1, Tree[rt].flag); Tree[rt].flag = -1; } int mid = (Tree[rt].l + Tree[rt].r) / 2; if(R <= mid) return query(L, R, rt*2); else if(L > mid) return query(L, R, rt*2+1); else{ node t1, t2, t3; t1 = query(L, mid, rt*2); t2 = query(mid+1, R, rt*2+1); t3.cnt1 = t1.cnt1 + t2.cnt1; t3.l1 = t1.l1; if(t1.l1 == t1.len) t3.l1 += t2.l1; t3.r1 = t2.r1; if(t2.r1 == t2.len) t3.r1 += t1.r1; t3.max1 = max(t1.max1, t2.max1); t3.max1 = max(t3.max1, t1.r1 + t2.l1); t3.len = t1.len + t2.len; return t3; }}int main(){ int n, m; while(scanf("%d%d",&n,&m) != EOF) { for(int i = 1; i <= n; i++) scanf("%d", &A[i]); Build(1, n, 1); int op, a, b; for(int i = 1; i <= m; i++){ scanf("%d%d%d",&op,&a,&b); a++; b++; if(op <= 2){ update(a, b, 1, op); } else{ node ans = query(a, b, 1); if(op == 3){ printf("%d\n",ans.cnt1); } else{ printf("%d\n",ans.max1); } } } } return 0;}
【D】贪心+排序,按比率排,避免小数,所以讲式子进行转换
【代码君】
////Created by just_sort 2016/12/1//Copyright (c) 2016 just_sort.All Rights Reserved//#include <ext/pb_ds/assoc_container.hpp>#include <ext/pb_ds/tree_policy.hpp>#include <ext/pb_ds/hash_policy.hpp>#include <set>#include <map>#include <queue>#include <stack>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;using namespace __gnu_pbds;typedef long long LL;typedef pair<int, LL> pp;#define MP(x,y) make_pair(x,y)const int maxn = 200005;typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>order_set;//headstruct node{ int dps, hp; node(){} node(int dps, int hp):dps(dps), hp(hp){} bool operator <(const node &rhs) const{ return (hp*rhs.dps) < (dps*rhs.hp); } void read(){ scanf("%d%d",&dps,&hp); }}a[22];int main(){ int n; while(scanf("%d",&n)!=EOF) { for(int i = 0; i < n; i++) a[i].read(); sort(a, a + n); int sum = 0; int ans = 0; for(int i = 0; i < n; i++){ sum = sum + a[i].dps; } for(int i = 0; i < n; i++){ ans = ans + sum * a[i].hp; sum = sum - a[i].dps; } printf("%d\n", ans); } return 0;}
【E】 将不小于m的数看成1,剩下的看成0,只要区间1的个数不小于k就可以,枚举区间左端点,右端点可以通过two-pointers求出,时间复杂度O(n)
【代码君】
////Created by just_sort 2016/12/1//Copyright (c) 2016 just_sort.All Rights Reserved//#include <ext/pb_ds/assoc_container.hpp>#include <ext/pb_ds/tree_policy.hpp>#include <ext/pb_ds/hash_policy.hpp>#include <set>#include <map>#include <queue>#include <stack>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;using namespace __gnu_pbds;typedef long long LL;typedef pair<int, LL> pp;#define MP(x,y) make_pair(x,y)const int maxn = 200005;typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>order_set;//headint a[maxn];int n, m, K;LL ans;int main(){ int T, n; scanf("%d",&T); while(T--){ scanf("%d%d%d", &n,&m,&K); for(int i = 1; i <= n; i++) scanf("%d",&a[i]); ans = 0; int r = 0, num = 0; for(int i = 1; i <= n; i++){ while(num < K && r <= n){r++; num += (a[r] >= m);} if(num < K) break; ans += n - r + 1; num -= (a[i] >= m); } printf("%lld\n",ans); } return 0;}
0 0
- 【玩耍】一水
- 玩耍
- [玩耍]俄罗斯方块
- 配置一个ubuntu,任我玩耍任我游 (一)
- OpenCV玩耍(一)批量resize一个文件夹里的所有图像
- 和Linux大魔王愉快的玩耍(一)环境变量和文件类型
- [玩耍]贪吃蛇
- 9.17ACM玩耍记
- [玩耍]C++控制台扫雷
- 愉快玩耍GitHub
- 个人android 2048的玩耍
- 玩耍 - JAVA写的五子棋
- hackerrank University CodeSprint玩耍记
- Android玩耍之路20161128
- [玩耍]JS实现几何星空
- 童年十大经典玩耍游戏
- 玩耍电脑时遇到得各种问题
- 这个周六要出去玩耍咯
- 控制软键盘显示和隐藏
- 不展现报表实现对报表的打印导出
- 安卓MVP浅析及Presenter的生命周期问题
- Ajax 学习笔记(一)
- 讲述建站经历-珍惜网talk888888.com
- 【玩耍】一水
- ListView的右边滚动滑块启用方法
- LinkedList
- 《人月神话》-巴比伦塔为什么会失败?
- 微信小游戏,H5游戏,微信吸粉小游戏
- 更新VS+Qt项目(从VS2010+Qt5.4.0到VS2012+Qt5.2.1)
- 整合SSM三大框架的思路
- Fresco-Facebook介绍
- AsyncTask实现原理和内部代码