2019 HZNU Winter Training Day 13 Comprehensive Training
A.Jongmah CodeForces-1110D
题意:你在玩一个数字游戏,有一堆写在瓦片上的数字,希望你能组成最多的三元组(三个数字相同,或顺子)。
这题用到的方法是动态规划.f[i][j][k]表示为i的数字中,属于组成三个连续数字三元组的开头的有k 个,属于组成三个连续数字的三元组的中间的有j个,由于连续三个的数字组成三元组的数量不会大于等于三个,如果大于等于的话就是不会更优的,那么转移方程为:
f[i+1][j][k]=max(f[i+1][j][k],f[i][k][l]+l+(a[i]−(j+k+l))/3)
a[i] 表示i 这个数字的出现次数,最后f[m][0][0]就是答案。
代码:
- /*
- I have a dream!A AC deram!!
- orz orz orz orz orz orz orz orz orz orz orz
- orz orz orz orz orz orz orz orz orz orz orz
- orz orz orz orz orz orz orz orz orz orz orz
- */
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- #include<cstring>
- #include<cmath>
- #include<string>
- #include<algorithm>
- #include<vector>
- #include<queue>
- #include<set>
- #include<stack>
- #include<map>
- using namespace std;
- typedef long long ll;
- const int maxn = 1e6 + ;
- const int N = ;
- ll f[maxn][][], a[maxn];
- inline int read()
- {
- int x = , f = ; char ch = getchar(); for (; !isdigit(ch); ch = getchar())if (ch == '-')f = -;
- for (; isdigit(ch); ch = getchar())x = x * + ch - ''; return x * f;
- }
- int main()
- {
- int n=read(), m=read();
- for (int i = ; i <= n; i++)
- a[read()]++;
- memset(f, -0x3f, sizeof(f));
- f[][][] = ;
- for (int i = ; i <= m; i++)
- for (int x = ; x < ; x++)
- for(int y = ; y<; y++)
- for (int z = ; z < ; z++)
- {
- if (a[i] < x + y + z)
- continue;
- f[i][x][y] = max(f[i][x][y], f[i - ][z][x] + (a[i] - x - y - z) / + z);
- }
- printf("%lld\n", f[m][][]);
- //system("pause");
- return ;
- }
B.Ball CodeForces-12D
题意:一群女士来到国王的宫殿参加聚会,每位女士都拥有三个属性值:美貌,财富和智慧。当出现一位A女士的每个属性值严格大于另一位B女士的时候,B女士就会跳窗,即满足如下等式:Bi < Bj, Ii < Ij, Ri < Rj 。
方法:线段树降维。先将 y 属性离散化,按照离散后的值作为下标建立线段树。接着按照 x 属性从大到小排序,然后依次遍历,这时可以肯定的是当前正在处理到的人她的x值肯定小于之前被更新到线段树里的人的x值。更新线段树时,每更新到一个人 i ,就在她对应的 yi 下标赋值 zi。这样我们在查询一个人 j 是否会狗带时,只需要查询区间[yj+1,Size]的最大值,这个最大值和 zj 进行比较就可以啦。好巧妙的处理方法呀,相当于人是排队依次进来的,降低了1维后变成二维,再在y的位置上放置这个高度为z的人。
作者:Amovement
来源:CSDN
原文:https://blog.csdn.net/amovement/article/details/86568141
版权声明:本文为博主原创文章,转载请附上博文链接!
代码:
- /*
- I have a dream!A AC deram!!
- orz orz orz orz orz orz orz orz orz orz orz
- orz orz orz orz orz orz orz orz orz orz orz
- orz orz orz orz orz orz orz orz orz orz orz
- */
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- #include<cstring>
- #include<cmath>
- #include<string>
- #include<algorithm>
- #include<vector>
- #include<queue>
- #include<set>
- #include<stack>
- using namespace std;
- typedef long long ll;
- typedef unsigned long long ull;
- const int N = ;
- #define pa pair<int,int>
- inline int read()
- {
- int x = , f = ; char ch = getchar(); for (; !isdigit(ch); ch = getchar())if (ch == '-')f = -;
- for (; isdigit(ch); ch = getchar())x = x * + ch - ''; return x * f;
- }
- int n;
- const int maxn = 5e5 + ;
- struct Node
- {
- int x, y, z;
- }a[maxn];
- int h[maxn];
- struct Tree
- {
- int l, r, maxx;
- };
- Tree node[maxn << ]; //node[maxn]为线段树处理数组
- void PushUp(int i)
- {
- node[i].maxx = max(node[i << ].maxx, node[(i << ) | ].maxx);
- }
- void build(int i, int l, int r)
- {
- node[i].l = l; node[i].r = r;
- if (l == r)
- {
- node[i].maxx = ;
- return;
- }
- int mid = (l + r) / ;
- build(i << , l, mid);
- build((i << ) | , mid + , r);
- PushUp(i);
- }
- int getmax(int i, int l, int r)
- {
- if (node[i].l == l && node[i].r == r)
- return node[i].maxx;
- int mid = (node[i].l + node[i].r) / ;
- if (r <= mid) return getmax(i << , l, r);
- else if (l > mid) return getmax((i << ) | , l, r);
- else return max(getmax(i << , l, mid), getmax((i << ) | , mid + , r));
- }
- void add(int i, int k, int v)
- {
- if (node[i].l == k && node[i].r == k)
- {
- node[i].maxx = max(node[i].maxx, v);
- return;
- }
- int mid = (node[i].l + node[i].r) / ;
- if (k <= mid) add(i << , k, v);
- else add((i << ) | , k, v);
- PushUp(i);
- }
- bool cmp(Node xx, Node yy)
- {
- if (xx.x != yy.x)return xx.x > yy.x;
- else if (xx.y != yy.y)return xx.y > yy.y;
- else return xx.z > yy.z;
- }
- int main()
- {
- scanf("%d", &n);
- for (int i = ; i <= n; i++)scanf("%d", &a[i].x);
- for (int i = ; i <= n; i++)scanf("%d", &a[i].y), h[i] = a[i].y;
- for (int i = ; i <= n; i++)scanf("%d", &a[i].z);
- sort(h + , h + + n);
- int Size = unique(h + , h + + n) - h - ;
- build(, , Size + );
- sort(a + , a + + n, cmp);
- int preval = a[].x;
- int prei, ans = ;
- //printf("----------\n");
- for (int i = ; i <= n;)
- {
- prei = i;
- for (; a[i].x == a[prei].x&&i <= n; i++)
- {
- //printf("%d %d %d\n",a[i].x,a[i].y,a[i].z);
- a[i].y = lower_bound(h + , h + + Size, a[i].y) - h;
- //printf("%d %d\n",a[i].y+1,Size+1);
- if (getmax(, a[i].y + , Size + ) > a[i].z)ans++;
- }
- for (; prei < i; prei++)
- {
- add(, a[prei].y, a[prei].z);
- }
- }
- printf("%d\n", ans);
- }
C.Robot Gym-101915G
题意:机器人在树上进行比赛,一棵树拥有n个结点和n-1条边,每条边拥有权重Wi。每个机器人有一个能力值Xi,只有当Xi>Wi的时候,机器人才能通过这条路径。
当然,如果出现几条路径都可以通过的时候,机器人会选择较大的一条路径。
最后求的是每个机器人最后到达的结点的和。
方法:贪心。
代码:
D.String of CCPC ZOJ-3985
题意:在一串字符串中数有几个CCPC,一个CCPC具有一个价值,你也可以购买C和P,第i次购买会花费i-1个价值。所以最好的情况就是只够买一次。
方法:先遍历一遍字符串,记录CCPC的数量,然后在遍历一次,找到几个特殊情况进行判断。
代码:
- /*
- I have a dream!A AC deram!!
- orz orz orz orz orz orz orz orz orz orz orz
- orz orz orz orz orz orz orz orz orz orz orz
- orz orz orz orz orz orz orz orz orz orz orz
- */
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- #include<cstring>
- #include<cmath>
- #include<string>
- #include<algorithm>
- #include<vector>
- #include<queue>
- #include<set>
- #include<stack>
- #include<map>
- using namespace std;
- typedef long long ll;
- const int maxn = 1e5 + ;
- const int N = ;
- char s[];
- int main()
- {
- int T;
- scanf("%d", &T);
- while(T--)
- {
- int len,flag,ans=;
- scanf("%d", &len);
- scanf("%s", s);
- for (int i = ; i < len; i++)
- {
- if (s[i] == 'C'&&s[i + ] == 'C'&&s[i + ] == 'P'&&s[i + ] == 'C')
- ans++;
- }
- for (int i = ; i < len; i++)
- {
- flag = ;
- if (s[i] == 'C'&&s[i + ] == 'P'&&s[i + ] == 'C')
- {
- if (i - < || s[i - ] != 'C')
- flag++;
- }
- else if (s[i] == 'C'&&s[i + ] == 'C'&&s[i + ] == 'P'&&s[i + ] != 'C')
- flag++;
- else if (s[i] == 'C'&&s[i + ] == 'C'&&s[i + ] == 'C')
- {
- if (s[i + ] == 'P'&&s[i + ] == 'C')
- flag--;
- flag++;
- }
- if (flag > )
- {
- ans++;
- break;
- }
- }
- printf("%d\n", ans);
- }
- return ;
- }
E.Drazil and Tiles CodeForces-516B
题意:给你一块n*m的格子,希望你用1*2的砖块铺满。瓷砖拥有的形态是“<>”和“^v”,图上“.”表示格子为空,需要被铺上瓷砖,“*”表示已经被铺上,不需要再铺。如果拥有独一无二的铺满的方法就画出铺上瓷砖的格子,如果不存在铺满的情况或者有多种情况出现,就输出“Not unique”。
方法:先统计每个空格子旁边有几个空格子,用二维数组d[][]记录(即有几种方法填满)。然后开一个队列,将只有一种方法铺满的格子扔进去,更新邻近的点,更新d[][]。最后如果仍有“.”,即说明不满足题目要求。
代码:
- /*
- I have a dream!A AC deram!!
- orz orz orz orz orz orz orz orz orz orz orz
- orz orz orz orz orz orz orz orz orz orz orz
- orz orz orz orz orz orz orz orz orz orz orz
- */
- #include<iostream>
- #include<cstdio>
- #include<cstdlib>
- #include<cstring>
- #include<cmath>
- #include<string>
- #include<algorithm>
- #include<vector>
- #include<queue>
- #include<set>
- #include<stack>
- #include<map>
- using namespace std;
- typedef long long ll;
- const int maxn = 1e6 + ;
- const int N = ;
- #define pa pair<int,int>
- inline int read()
- {
- int x = , f = ; char ch = getchar(); for (; !isdigit(ch); ch = getchar())if (ch == '-')f = -;
- for (; isdigit(ch); ch = getchar())x = x * + ch - ''; return x * f;
- }
- int n, m, dx[] = { ,-,, }, dy[] = { ,,,- }, d[N][N];
- char mp[N][N];
- queue<pa>q;
- int main()
- {
- n = read(), m = read();
- for (int i = ; i <= n; i++)
- scanf("%s", mp[i] + );
- for(int x=;x<=n;x++)
- for (int y = ; y <= m; y++)
- {
- if (mp[x][y] == '*')
- d[x][y] = ;
- else
- for (int i = ; i < ; i++)
- {
- int xx = x + dx[i], yy = y + dy[i];
- if (xx< || xx>n || yy< || yy>m || mp[xx][yy] == '*')
- continue;
- d[x][y]++;
- }
- }
- for (int i = ; i <= n; i++)
- for (int j = ; j <= m; j++)
- if (d[i][j] == )
- q.push(make_pair(i, j));
- while (!q.empty())
- {
- int x = q.front().first, y = q.front().second;
- q.pop();
- if (d[x][y] == ) continue;
- for (int i = ; i < ; i++)
- {
- int xx = x + dx[i], yy = y + dy[i];
- if (xx< || xx>n || yy< || yy>m || mp[xx][yy] != '.')
- continue;
- d[x][y] = d[xx][yy] = ;
- if (i == ) mp[x][y] = '^', mp[xx][yy] = 'v';
- if (i == ) mp[x][y] = 'v', mp[xx][yy] = '^';
- if (i == ) mp[x][y] = '<', mp[xx][yy] = '>';
- if (i == ) mp[x][y] = '>', mp[xx][yy] = '<';
- for (int j = ; j < ; j++)
- {
- int xxx = xx + dx[j], yyy = yy + dy[j];
- if (xxx< || xxx>n || yyy< || yyy>m || mp[xxx][yyy] != '.')
- continue;
- if (--d[xxx][yyy] == )
- q.push(make_pair(xxx, yyy));
- }
- }
- }
- for (int i = ; i <= n; i++)
- for(int j = ; j <= m; j++)
- if (mp[i][j] == '.')
- {
- printf("Not unique\n");
- return ;
- }
- for (int i = ; i <= n; i++)
- puts(mp[i] + );
- system("pause");
- return ;
- }
F.How can I satisfy thee? Let me count the ways... ZOJ - 3025
题意:输入一个式子,里面具有变量,常量和运算符号,变量P,Q,R取值为0,1,2这三个常量,然后有-,*,+三个运算规则。最后问让一个式子最后答案为2的方法有多少种(即让变量取不同的值)。
方法:暴力。先把式子转成后缀表达式。然后总共的可能就是3*3*3,进行暴力求解即可。
代码:
2019 HZNU Winter Training Day 13 Comprehensive Training的更多相关文章
- 2019 HZNU Winter Training Day 15 Comprehensive Training
A - True Liars 题意: 那么如果一个人说另一个人是好人,那么如果这个人是好人,说明 对方确实是好人,如果这个是坏人,说明这句话是假的,对方也是坏人. 如果一个人说另一个人是坏人,那么如果 ...
- 2019 HZNU Winter Training Day 14 Comprehensive Training
A - Choosing Capital for Treeland CodeForces - 219D 题意:有一颗单向边的树,要选取一个结点作为首都.要求是这个结点到其它结点,总共需要翻转的路径数量 ...
- 2019 wannafly winter camp day 3
2019 wannafly winter camp day 3 J 操作S等价于将S串取反,然后依次遍历取反后的串,每次加入新字符a,当前的串是T,那么这次操作之后的串就是TaT.这是第一次转化. 涉 ...
- 2019 wannafly winter camp
2019 wannafly winter camp Name Rank Solved A B C D E F G H I J K day1 9 5/11 O O O O O day2 5 3/11 O ...
- 【Android Developers Training】 13. 支持不同平台版本
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- hdu 3038 How Many Answers Are Wrong(种类并查集)2009 Multi-University Training Contest 13
了解了种类并查集,同时还知道了一个小技巧,这道题就比较容易了. 其实这是我碰到的第一道种类并查集,实在不会,只好看着别人的代码写.最后半懂不懂的写完了.然后又和别人的代码进行比较,还是不懂,但还是交了 ...
- 2019 wannafly winter camp day1-4代码库
目录 day1 F div1 爬爬爬山 (最短路) B div2 吃豆豆 (dp) J div2 夺宝奇兵(暴力) J div1 夺宝奇兵 (权值线段树) C div1 拆拆拆数 E div1 流流流 ...
- 2019 CCPC-Wannafly Winter Camp Day1 (Div2, onsite)
solve:4/11 补题:6/11 A 机器人 补题:zz 这是一道分类讨论的题目,有一个规律就是如果必须要从第一个区到第二个区,那么最多转区两次(1到2一次,2到1一次),然后分类讨论即可,只要细 ...
- 2019 CCPC-Wannafly Winter Camp Day2(Div2, onsite)
solve 4/11 A Erase Numbers II Code:KK Thinking :KK 用ans表示当前最优答案,maxx表示遍历到的最大数字,一开始ans肯定等于a[ 1 ]+a[ 2 ...
随机推荐
- python3 实现多域名批量访问特定目录(一)
渗透测试之批量处理同一框架CMS系统漏洞 当我们做多网站的渗透测试时,会发现很多站点采用的都是同类型的CMS框架,只要我们发现一个漏洞,那么我们可以批量处理这一类站点,高效测试,如果不知道该站点的框架 ...
- 重入锁的学习 (ReentrantLock)
重入锁 :(ReentrantLock) 上锁 用reentrantLock.lock 方法 解锁 用reentrantLock.unlock 方法 上锁和解锁 必须配对 可以多重上锁 Reentr ...
- Danjgo学习笔记(一)
## 创建项目: 1. 通过命令行的方式:首先要进入到安装了django的虚拟环境中.然后执行命令: ``` django-admin startproject [项目的名称] ``` 这样就可以在当 ...
- Maven安装配置及其插件m2e(Eclipse Indigo 和 MyEclipse8.5)的安装配置
Maven安装配置及其插件m2e(Eclipse Indigo 和 MyEclipse8.5)的安装配置 系统:Windows7 使用软件: Maven3.0.3 + Eclipse Indigo ...
- 《机器学习技法》---GBDT
1 对决策树使用adaboost 对决策树使用adaboost时,有以下几个问题: (1)adaboost每次更新的样本权重如何应用到决策树中? 由于我们不知道决策树的err目标是什么,因此通常的方法 ...
- 安利一个免费下载VIP文档神器
今天安利给大伙一个非非非常好用的可以免费下载VIP文档的下载神器------冰点文库下载器,用过的人都说好.操作简单,小巧轻便,完全免费.支持百度.豆丁.畅享.mbalib.hp009.max.boo ...
- VU TPS QPS RT 计算公式
1.背景 最近看了阿里巴巴中间件写的一篇文章,讲述了关于并发,RPS,RT之间的关系.感觉收获颇丰.自己使用JMeter工具对公式进行了验证. 2.验证 我们先来看几个基础知识定义: TPS:每秒完成 ...
- set集合的常用方法
set集合是一种无序不重复的集合 add (self, *args, **kwargs) ...
- hive动态分区与静态分区
测试目的:1.分区表的动态分区与静态分区2.每层数据,数据流向,数据是否在每层都保留一份测试结果:1.动态分区/静态分区略2.每层表的数据都会保留,因此在生产上odm层的数据是可以删除的(不管是内表还 ...
- 彻底搞懂Java中equals和==的区别
java当中的数据类型和“==”的含义: 1.基本数据类型(也称原始数据类型) :byte,short,char,int,long,float,double,boolean.他们之间的比较,应用双等号 ...