
夯实基础
文章平均质量分 65
ww32cc
这个作者很懒,什么都没留下…
展开
-
Codeforces Round #273 (Div. 2) C.Table Decorations 贪心
思路:每个桌子的三个气球只有两种情况:1 + 1 + 1或者 2 + 1使用贪心的策略,每次使用2 + 1的放法。先将三种气球按数量排序,不失一般性,令r, g, b的数目有 所以基本放法是:bb + (r / g)。所以按照2 +1的策略放,到最后有两种情况:①r和g无剩余;②r,g有剩余;① r和g无剩余 ,此时只有b剩余,不能装饰新的桌子,故解为 ② r,g有剩余 ,此时原创 2015-07-14 15:19:06 · 544 阅读 · 0 评论 -
poj3635 Full Tank? 最短路+dp
思路:根据题意很容易想到动态规划方程,,状态dp[i][j]表示到达i时油量剩余j,但是复杂度太高。从另一个角度想,由一个最优解产生另一个最优解,每次取最优解的节点进行扩展,类似dijkstra最短路。具体处理如下:每次取一个最优节点出队,则节点为队中到源点花费最小的,在该状态下,可以选择购买1单位的油,也可以走向其邻节点。为什么是购买1单位的油?假设此时队首油量为j,在该点最多可以购原创 2015-08-26 09:36:58 · 550 阅读 · 0 评论 -
Codeforces Round #291 (Div. 2) D. R2D2 and Droid Army RMQ/单调队列/尺取法
题意:M种detail的序列,求这样的区间:区间内每种detail的最大值之和小于数值K,求区间的最大长度。解法一:二分+区间最大值(RMQ或单调队列)由于是求最大长度,而给定一个长度我们可去check是否为合法解,所以可以使用二分。①区间最大值RMQ问题可以使用线段树、ST算法(sparse table)降低查询复杂度。线段树和ST算法预处理需要O(nlogn),线段树查询需要O(l原创 2015-08-10 15:53:50 · 641 阅读 · 0 评论 -
Codeforces Round #291 (Div. 2) C. Watto and Mechanism Trie字典树+dfs
思路:由于字符串长度上限为6*10^5,直接比较十分耗时。所以使用trie进行查找。原创 2015-08-04 15:56:35 · 640 阅读 · 0 评论 -
Codeforces Round #286 (Div. 2) B. Mr. Kitayuta's Colorful Graph dfs
思路:因为color种类不超过100种,根据题目数据量,直接对每种color进行枚举,再进行dfs判断该种颜色下两点是否连同即可。代码如下:#include #include using namespace std;#define N 105int head[N][N], idx;struct Edge{ int to, next;}edges[N * 2];bool原创 2015-07-30 12:12:56 · 419 阅读 · 0 评论 -
Codeforces Round #281 (Div. 2) C. Vasya and Basketball 枚举+二分
思路:给定一个d,两队的分数可以在log(n)内求出:二分查找出最后一个不大于d的位置idx,则0~idx这idx+1次投球得分为2分,idx+1~n-1这n-idx-1次投球得分为3所以只需枚举二分线d即可。开始时在最大最小值之间枚举,复杂度O(10^9)超时。观察数据量,其实枚举m+n个数即可。下面证明两者得到的最优解是等价的:设最优解d,二分得到a队的位置为i,b队的位置为j,(d原创 2015-07-24 13:51:25 · 415 阅读 · 0 评论 -
Codeforces Round #278 (Div. 2) C. Fight the Monster 二分+枚举
二分所需的花费,对给定花费枚举hp、atk、def的购买数量。代码如下#include using namespace std;#define INF 30100#define max(a, b) (a) > (b) ? (a) : (b)int hp[2], atk[2], def[2];int h, a, d;bool check(int x){ int bound_h原创 2015-07-21 13:25:19 · 435 阅读 · 0 评论 -
Codeforces Round #287 (Div. 2) C. Guess Your Way Out! 二叉树遍历
思路:由样例可知,若exit和实际command在当前的父节点两边,则父节点一侧的子树节点必须全部遍历一遍,才会再次返回到父节点,从而转向正确的方向。故先求出exit的正确路径,然后与command相比,①若相同,则只需沿着command走,ans++②若不相同,则ans += 父节点左侧子树的节点数代码如下:#include using namespace std;#de原创 2015-07-31 14:25:55 · 529 阅读 · 0 评论 -
Codeforces Round #279 (Div. 2) B. Queue 模拟
思路:和中出现了0的行,代表的是队首和队尾元素,所以只需沿着两个0前向/逆向出发,即可将队列填满。由队尾给出的那一行一定为:ID[n - 1], 0,所以从0逆向出发能确定第n - 1个人,根据n的奇偶性进行判断:①当n为奇数时,从0前向出发,依次可以确定队列的第2,4,……,n - 1个人,所以应该从队尾元素逆向出发,确定队列的第n,n - 2,……,1个人②当n为偶数时,从0前向出原创 2015-07-22 13:31:08 · 420 阅读 · 0 评论 -
Codeforces Round #290 (Div. 2) C. Fox And Names 拓扑排序
思路:对相邻两行,当s1[i]≠s2[i]时,新的字母表中s1[i]必须出现在s2[i]的前面,显然是拓扑排序。所以枚举相邻的两行,构造有向边统计入度。拓扑排序:每次从图中拿走一个入度为0的节点,并删除所有从该点出发的有向边。若最终输出的节点个数小于总个数,证明存在环。代码如下:#include #include using namespace std;#define N 1原创 2015-08-03 15:28:19 · 461 阅读 · 0 评论 -
Codeforces Round #284 (Div. 2) C. Crazy Town 数学
思路:只有当两个点不被任何直线分隔开时,两个点才算在同一区域内。所以当两个点位于一条直线的两侧时,就需要跨过这条直线,扫描所有的road即可。代码如下:#include using namespace std;int main(){ int x1, y1, x2, y2; scanf("%d %d %d %d", &x1, &y1, &x2, &y2); int n; s原创 2015-07-28 09:46:26 · 641 阅读 · 0 评论 -
Codeforces Round #280 (Div. 2) D. Vanya and Computer Game 数学+预处理
思路:由于hit的时间涉及浮点数,处理起来较繁琐,所以可以换一种思路。由于所有的monster同时被attack,所以处理1s内的情况即可。预处理一秒内两个人的hit顺序,若同时hit则记为BOTH。预处理hit次序只需按次数进行扫描,设当前VANYAhit次数为hit_x,VOVA为hit_y,则VANYA的下一次hit时刻为(hit_x + 1)/x,VOVA的下一次hit时刻为(hit_原创 2015-07-23 18:06:18 · 461 阅读 · 0 评论 -
Codeforces Round #279 (Div. 2) C. Hacking Cypher 大数除法+枚举
思路:刚开始使用大数除法,枚举分割点,复杂度O(n^2)肯定超时。除法代码如下:但是仔细观察发现,在使用大数除法的时候原创 2015-07-22 14:00:10 · 633 阅读 · 0 评论 -
Codeforces Round #276 (Div. 2) C. Bits 二进制
思路:所求数x满足,设l和r的二进制表示为:,且l的长度小于等于r。则l和r不等的情况下,设,则小于i的位可以全部取1,大于i的位与l和r相同:。第i位处理如下:第i位取0一定满足,所以考虑取1的情况,若取1时满足条件,则可取1(此时,但不需要特别讨论);若取1时超过了r,则取0。代码如下:#include using namespace std;int l_digit[181原创 2015-07-17 11:40:46 · 432 阅读 · 0 评论 -
LeetCode Largest Number 贪心
将数组中的元素进行重排,组成最大的数。如果只有两个数,可以简单判断:,使用贪心,将数组中的元素按照上述比较规则进行降序排序,进行拼接即为所求。证明如下:假设按照贪心得到的最优解为:(其中),若存在解(和交换位置)比更优。令和之间一共位,则有:原创 2016-02-10 22:03:41 · 532 阅读 · 0 评论 -
Moore's majority vote algorithm
求n个数中出现次数超过原创 2016-02-08 11:19:23 · 406 阅读 · 0 评论 -
poj1184 聪明的打字员 BFS+剪枝
思路:题意很直观,用密码+光标位置来表示状态,对光标所在位置分别进行六种操作,得到新状态入队。但一共有1000000*6种状态,所以需要剪枝。由于swap0和swap1这两个交换操作只对光标处和0, 5位置的数字有效,当光标在j处时(0代码如下:#include #include #include using namespace std;#define N 1000005#d原创 2015-08-26 22:18:56 · 1492 阅读 · 1 评论 -
Codeforces Round #283 (Div. 2) B. Secret Combination 构造+枚举
思路:因为加法操作和移位操作都是对整体进行,所以最终的结果与两种操作的执行次序无关。可以先执行加法若干次,最后再执行移位操作,而加法最多执行9次又回到原来的数,枚举加法次数和移位次数即可。代码如下:#include #include #include using namespace std;#define N 1005char s[N], add[N], rot[N], min_原创 2015-07-26 12:46:40 · 477 阅读 · 0 评论 -
Codeforces Round #283 (Div. 2) C. Removing Columns 模拟+构造
注意行之间的比较结果与高位的字符有关,若s1[i] 使用布尔数组来记录相邻行之间的大于关系,若flag[i + 1][i] = true,说明前导字符已经满足字典序升序。否则需要对字符进行判断。注意对该列处理完之后,若保留该列,相邻行之间存在大于关系时需要对flag进行更新。代码如下:#include using namespace std;#define N 105char a原创 2015-07-26 13:04:18 · 490 阅读 · 0 评论 -
Codeforces Round #273(Div2) B. Random Teams 贪心+数学
最大值:n个人,其中m-1个队中只有一个人,剩下的人都放在一个组里最小值:每一组的人数尽量平均证明:最小值:令第i个team人数为xi, 则所求为.则又: .故整理得: ,当且仅当时,f取得最小值所以当n整除m时,f取得最小值.当n不整除m时,n % m部分有两种选择:①给其中n % m个team每个team多加一个人;②其中一只team多加原创 2015-07-14 16:06:27 · 741 阅读 · 0 评论 -
Codeforces Round #274(Div2) B. Towers 贪心
解法一:复杂度为O(nk)每次从最大值向最小值移动1个代码如下:#include using namespace std;#define N 1005int a[105], ans[N][2];int main(){ int n, k, ops = 0, max_val, min_val; scanf("%d %d", &n, &k); for(int i = 1; i原创 2015-07-15 14:04:44 · 563 阅读 · 0 评论 -
Codeforces Round #274(Div2) C. Exams 贪心
由于最后写在纸上的day number(ai)是不下降的,所以按规定时间(ai)排序的exam序列就是实际参加的考试顺序.在这一点的基础上,尽量让先参加的考试天数小(尽量取候选时间bi)代码如下:#include #include using namespace std;#define N 5005struct Node{ int a, b; friend bool op原创 2015-07-15 14:37:21 · 540 阅读 · 0 评论 -
Codeforces Round #275(Div2) B.Friends and Presents 二分+数学
将n个数分为三部分,则对这三个集合的数处理如下:i. 中的元素,除去x和y的公倍数,全部都可以给朋友aii. 中的元素,除去x和y的公倍数,全部都可以给朋友biii. 中的元素,给朋友a或者朋友b都可以不考虑两个人所需的cnt数,n个数中除去公倍数后满足条件:将中的元素全部给a,则a还需个将中的元素全部给b,则b还需个则二者还需要的部分,从取即可由于原创 2015-07-16 12:34:48 · 504 阅读 · 0 评论 -
Codeforces Round #275 (Div. 2) C. Diverse Permutation 构造
根据数据范围,从permutation考虑肯定会超时,考虑到k + 1个数一定可以构造出k种差值,则可以由已知解向所求解转换——使k + 1以后的数只产生1即可。具体构造方式:从第k + 1的位置开始从后向前放置,放置1,k+1,放置2,k……,则可以构造出1~k这k种差值最后的效果为:……2,k,1,k+1,k+2,……,n代码如下:#include #define N 100原创 2015-07-16 20:19:02 · 438 阅读 · 0 评论 -
Codeforces Round #276 (Div. 2)A. Factory 数学+规律
a % m只有m种可能,若某个余数是之前出现过的,那么接下来的余数一定会陷入循环,故生产不会停止。由于只要出现0便会停止,由鸽巢原理,m次操作里面没有出现0的话,则第m次一定会得到1 ~ m - 1之间的数,则进入循环。所以只需检测m次操作中是否出现0即可代码如下:#include using namespace std;int main(){ long long a; int原创 2015-07-17 11:10:46 · 401 阅读 · 0 评论 -
Codeforces Round #276 (Div. 2) B. Valuable Resources 二分
由于边界与坐标轴平行,则只需确定正方形的左下角和边长即可确定正方形。而左下角可以根据mines的坐标确定,所以只需二分枚举正方形的边长即可,给定边长,O(n)时间内可以检查是否满足。代码如下:#include #define N 1005#define INF 1000000001int x[N], y[N], n, orig_x = INF, orig_y = INF;bo原创 2015-07-17 11:12:31 · 480 阅读 · 0 评论 -
hdu5501 The Highest Mark 贪心+动态规划
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5501思路:首先将问题简单化,每道题有ti的时间消耗,给定T时间内要完成若干题目使得分值最大,很容易想到背包问题。但是本题中的value是随着时间减小的,因此背包的顺序也会影响最优值。如果物品数量的规模在16左右,可以使用状态压缩来做:,其中,dp[i][j]表示j分钟结束时状态为i,k为题目的标号原创 2015-10-11 14:37:31 · 416 阅读 · 0 评论 -
hdu5500 Reorder the Books 贪心
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5500思路:问题等价为,一个1~n组成的序列,每次从中取出一个数,插到最前面,用最少的步骤使序列变为升序。其实在整个操作过程中,我们只需要保持相对顺序即可。每次操作保证pos[i - 1] < pos[i],即:i - 1出现在i的前面。如:首先检查n - 1是否出现在n前面,不是的话将n - 1移原创 2015-10-11 10:03:35 · 434 阅读 · 0 评论 -
Codeforces Round #288 (Div. 2) C. Anya and Ghosts 贪心
思路:由于一个candle只能覆盖t,所以对某一时刻w[i],最早的candle点亮时间不超过w[i] - t。否则w[i]时刻该candle已经熄灭。所以对每个w[i],统计w[i] - t ~ w[i] - 1之间有多少根蜡烛被点亮即可。若已有r个candle,不做任何处理。否则,由近及远点亮需要的candle。代码如下:#include using namespace std;原创 2015-08-02 14:40:33 · 510 阅读 · 0 评论 -
LeetCode : Regular Expression Matching DFS/动态规划
思路:由于*匹配存在不确定性,所以使用常规解法比较麻烦。由于问题可以分解,若S的前i个字符与P的前j个字符已经匹配,则只需考察剩余的字符即可。从这个特点上,可以使用DFS。而由于无后效性,所以也可以使用DP。1.DFS解法讨论p当前位置处的字符,若为'*',则s可以与p匹配0个或若干个字符,否则各自移动一个位置,对剩下的字符串递归处理。代码如下:class Solution {p原创 2015-10-25 19:02:19 · 1072 阅读 · 0 评论 -
Codeforces Round #286 (Div. 2) C. Mr. Kitayuta, the Treasure Hunter dp+范围压缩
思路:题目很直观,用dp[i][j]表示走到第i个island,jump值为j时的最优值,但是状态的数据量均为30000,超内存。由于d每次最多只能改变1,考虑d改变的最大幅度。设到达终点需跳x次,则有:当d = 1时,x dp[i][j]表示到达第i个island,jump值为d + (j - 250)时的最优解,求解时注意状态的有效性即可。 代码如下:#include #原创 2015-07-30 13:08:59 · 771 阅读 · 0 评论 -
Codeforces Round #282 (Div. 2) C. Treasure 贪心
思路:括号匹配问题可以用栈来模拟:遇左括号入栈,右括号出栈,最后栈空则匹配。所以beautiful字符串满足条件:①任意位置处左括号的数目不小于右括号②终点处左括号数目等于右括号从栈的处理过程可以看出,只要能使最终栈空,中间的右括号完全可以放在末尾处。用一个数组cnt[n]记录每一位置处多出来的左括号数,将每个“#”号当做一个右括号处理,由于要使cnt[len] = 0,所以对原创 2015-07-25 16:14:37 · 430 阅读 · 0 评论 -
Codeforces Round #277 (Div. 2) C. Palindrome Transformations 贪心
思路:只需处理字符串的一半,即:根据右半段来修改左半段。因为同时修改对称的两个字符,所需的操作数与修改一个字符是相等的。为了使操作数最小,应该按顺序来修改。由于对称性,可将pos > mid的情况转化为pos 此时有两种情况:①pos离mid较近,则应该按照pos——mid——0的顺序检查是否需要修改②pos离端点较近,则应该按照pos——0——mid的顺序检查是否需要修改处理原创 2015-07-20 16:46:20 · 404 阅读 · 0 评论 -
Codeforces Round #285 (Div. 2) C. Misha and Forest 构造
思路:无向无环图中边的条数不超过n - 1,故一定存在叶子节点。由于叶子节点的邻边可直接确定,可以直接输出。将叶子节点所在边移除,迭代处理所有的叶子节点,直到所有节点都处理完毕。代码如下:#include using namespace std;#define N (1u << 16)int deg[N], sum[N], leaves[N], edge[N][2];int ma原创 2015-07-29 12:14:19 · 431 阅读 · 0 评论 -
双向BFS及优化
单向BFS只从起点一端开始搜索,双向BFS则是从起点和终点两边扩展节点,当节点发生重合时即找到最优解。假设起点到终点深度为d,每个节点平均有n个分支,那么单向BFS需要扩展的节点个数为。而从起点终点同时扩展,则只需。实现方法为:维护两个队列,分别保存从起点和终点扩展到的下一层,这样保证了两个队列中的节点处于相同的深度(即:距离起点或者终点深度相同)。则当拓展到时一定发生重合,得到最优解。代原创 2016-02-27 16:33:04 · 7510 阅读 · 0 评论