算法之路
思维改变世界
flyawayl
打工人
展开
-
Hihocoder 1691 数字游戏 (思维)
广搜或深搜会超时,我用优化过的广搜超时了。思路 设原数组的为X" role="presentation">XXX,全排列中的某个数组为Y" role="presentation">YYY 存在这样的事实:对于原数组X" role="presentation">XXX的全排列,对每一种排列都可以经过操作2变成目标数组Y" role="presentation">YYY。这样能够覆原创 2018-01-29 19:57:47 · 537 阅读 · 0 评论 -
Hihocoder1690 AEIOU (动态规划)
分析题目要求: 1. 所有的a都在e和i之前,所有的e都在i之前; 2. 所有的o都在u之前。 仔细分析发现如下特点: * 其实a、e、i" role="presentation">a、e、ia、e、ia、e、i这三个字符和o、u" role="presentation">o、uo、uo、u这两个字符毫无关系,设给定字符串为S" role="原创 2018-01-31 15:46:49 · 534 阅读 · 0 评论 -
第八届蓝桥杯决赛 对局匹配
标题:对局匹配小明喜欢在一个围棋网站上找别人在线对弈。这个网站上所有注册用户都有一个积分,代表他的围棋水平。 小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配在一起。如果两人分差小于或大于KKK,系统都不会将他们匹配。 现在小明知道这个网站总共有NNN名用户,以及他们的积分分别是A1,A2,...ANA1,A2,...ANA_1, A_2, ... A_N。 小...原创 2018-01-15 21:23:12 · 3292 阅读 · 6 评论 -
PAT 1010. Radix (25)
此题高能,甲级里面难度算比较大的了!(其实也不难,关键没指明数据范围)思路: 最后的答案不止是≤36\leq36,也可能特别大(超过int, 达到 long long int)。不能用顺序查找,需用二分查找。 这题有一个特点:当待处理的字符串只有一位时,答案有多个;当长度大于一位时,只有一个正确答案(或者没有答案)。注意当radix很大的时候,可能会导致计算过程超出原创 2018-01-19 14:26:50 · 356 阅读 · 0 评论 -
cf B. Mishka and trip (数学)
题意 Mishka想要去一个国家旅行,这个国家共有nn个城市,1∼n1\sim n城市通过道路形成一个环,即第i个城市和第i+1i+1个城市之间有一条道路,此外城市11和nn之间有一条道路。这nn个城市中有kk个首中心城市,中心城市与每个城市(除了自己)之间有一条道路。第ii城市个城市有一个魅力值cic_i,经过一条连接第ii个和第jj个城市的道路的费用是ci∗cjc_i*c_j,求所有道路的费用原创 2017-10-17 22:26:25 · 408 阅读 · 0 评论 -
hihoCoder1330 数组重排
题意小Hi想知道,如果他每次都按照一种固定的顺序重排数组,那么最少经过几次重排之后数组会恢复初始的顺序?具体来讲,给定一个1 - N 的排列 P,小Hi每次重排都是把第 i 个元素放到第 Pi个位置上。例如对于 P = (2, 3, 1),假设初始数组是(1, 2, 3),重排一次之后变为(3, 1, 2),重排两次之后变为(2, 3, 1),重排三次之后变回(1, 2, 3)。被排数组中的元素可以原创 2017-09-17 11:10:40 · 488 阅读 · 0 评论 -
2017CCPC 网络选拔赛1003 Ramsey定理
Ramsey定理 任意6个人中,一定有三个人互为朋友,或者互相不是朋友。证明这里我就不证明了。下面链接有证明 鸽巢原理 Ramsey定理AC代码#include <stdio.h>#include <algorithm>using namespace std;const int maxn = 3000+5;bool r[maxn][maxn];int main() { i原创 2017-08-20 10:02:46 · 789 阅读 · 0 评论 -
UVALive - 3938 (线段树,区间查询)
思路:详细分析见训练指南P200P200。注意可能答案的起点在左区间,终点在右区间AC代码#include <stdio.h>#include <algorithm>using namespace std;typedef long long LL;typedef pair<int, int> pii;const int maxn = 500000+5;int dish[maxn];LL原创 2017-08-18 13:22:42 · 459 阅读 · 0 评论 -
PAT Public Bike Management (dfs)
思路:你的答案必须满足三个条件: 1.在所有路径中选择最短的; 2.如果路径相等,则选择从PBMC中送出最少的; 3.如果路径相等且PBMC送出的车也相等,则选择带回最少的。 注意:这题很恶心,你要考虑–在最后计算发车数和返回车数时,首先要从sp开始反向寻找第一个缺车的站(由于发车是单向的,路径上靠近PBMC的站可以将多出的车交给较远的缺车的站,但较远的站之后不能将多出的车返还给较近的缺车站原创 2017-08-14 08:54:28 · 400 阅读 · 0 评论 -
PAT All Roads Lead to Rome 单源最短路
思路:单源最短路末班就好了,字符串映射成数字处理。AC代码//#define LOCAL#include <stdio.h>#include <string.h>#include <algorithm>#include <queue>#include <map>#include <vector>#include <string>using namespace std;#define原创 2017-08-14 11:11:25 · 662 阅读 · 0 评论 -
有趣的排序 (贪心+思维)
题意:度度熊有一个N个数的数组,他想将数组从小到大 排好序,但是萌萌的度度熊只会下面这个操作: 任取数组中的一个数然后将它放置在数组的最后一个位置。 问最少操作多少次可以使得数组从小到大有序? 注意:题目中没有说明每个数是否唯一,我把它当做唯一的AC了。说明n个数中没有重复的!思路:以前在hihoCoder做过类似的题。设pos(i)pos(i)表示数字ii当前所在的位置,假设我们将数组AA排原创 2017-08-13 15:29:52 · 1001 阅读 · 0 评论 -
不等式数列 (动态规划)
题意:度度熊最近对全排列特别感兴趣,对于1到n的一个排列,度度熊发现可以在中间根据大小关系插入合适的大于和小于符号(即 ‘>’ 和 ‘<’ )使其成为一个合法的不等式数列。但是现在度度熊手中只有k个小于符号即(‘<”)和n-k-1个大于符号(即’>’),度度熊想知道对于1至n任意的排列中有多少个排列可以使用这些符号使其为合法的不等式数列。思路:dp(i,j)dp(i, j)表示已经使用数字1,2,3原创 2017-08-13 15:45:30 · 810 阅读 · 0 评论 -
买帽子 (hash)
思路:cnt[i]cnt[i]表示数字i出现的次数,在输入的同时记录每个数字出现的次数。最后从0枚举到1000判断第三个是否存在,存在则记录该数字。#include <stdio.h>#include <cstring>const int maxn = 1000+5;int cnt[maxn];int main() { int n; while(scanf("%d", &n)原创 2017-08-13 12:15:37 · 436 阅读 · 0 评论 -
度度熊回家 (模拟)
思路:先计算出从第0个坐标到第n-1个坐标的距离,然后枚举忽略[1,n−2][1, n-2]的点,直接可以得到需要走的距离。复杂度O(n)O(n),当然暴力枚举再重新计算也是可以AC的,复杂度O(n2)O(n^2)AC代码#include <stdio.h>#include <algorithm>using namespace std;#define inf 0x3f3f3f3fconst原创 2017-08-13 12:35:17 · 493 阅读 · 0 评论 -
寻找三角形 (海伦公式)
海伦公式:S=p∗(p−a)∗(p−b)∗(p−c)−−−−−−−−−−−−−−−−−−−−−−√S=\sqrt{p*(p-a)*(p-b)*(p-c)},其中a,b,ca,b,c是三角形边长,pp是三角形周长的一半。思路:枚举三角形的三个顶点,判断是否满足三个点的颜色要么全部相同,要么全部不同。AC代码#include <stdio.h>#include <math.h>#include <a原创 2017-08-13 13:03:23 · 1199 阅读 · 0 评论 -
地牢逃脱 (BFS)
题意:给定一个 n 行 m 列的地牢,其中 ‘.’ 表示可以通行的位置,’X’ 表示不可通行的障碍,牛牛从 (x0 , y0 ) 位置出发,遍历这个地牢,和一般的游戏所不同的是,他每一步只能按照一些指定的步长遍历地牢,要求每一步都不可以超过地牢的边界,也不能到达障碍上。地牢的出口可能在任意某个可以通行的位置上。牛牛想知道最坏情况下,他需要多少步才可以离开这个地牢。我必须说:出题人是智障!! 谁能看原创 2017-08-13 11:38:39 · 618 阅读 · 0 评论 -
合唱团 (线性dp)
题意:有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?思路:d(i,j,1)d(i, j, 1)表示在i个位置选了j人的最大乘积,d(i,j,1)d(i, j, 1)表示在i个位置选了j人的最小乘积。为什么要记录最小乘积?因为每个学生的能力值可能为正可原创 2017-08-13 10:21:19 · 467 阅读 · 0 评论 -
UVA - 11636 Hello World! (贪心)
思路:复制次数最少并且可以部分复制,那么贪心地让当前尽量多的复制,如果最后一次复制会超过n,那就部分复制。即满足(1<<x)≥n(1<<x) \geq n并且x尽量小。AC代码#include <stdio.h>const int maxn = 20;int bit[maxn];void init() { bit[0] = 1; for(int i = 1; i < maxn;原创 2017-08-12 17:39:14 · 651 阅读 · 0 评论 -
PAT1118. Birds in Forest (并查集)
思路:并查集一套带走。AC代码#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int maxn = 10000+5;int par[maxn], vis[maxn];int findRoot(int x) { return x == par[x] ? x : par[原创 2017-08-06 10:09:29 · 455 阅读 · 0 评论 -
PAT1119. Pre- and Post-order Traversals
思路:中序遍历–根结点,左子树,右子树;后序遍历–左子树,右子树,根结点。 那么在找到根结点之后就可以开始划分左右子树了。左子树的先序第一个节点是根,左子树的后序最后一个节点是根。 例如 1 2 3 4 6 7 5 2 6 7 4 5 3 1 当前的根结点就是1,在先序中得到左子树的根结点就是2,再在后序中知道左子树的节点就是{2},那么就得到左子树了,剩下的就是右子树。 如何判断重建的原创 2017-08-05 12:46:21 · 835 阅读 · 0 评论 -
PAT1116. Come on! Let's C (map)
思路:模拟一下就好了,map用来记录每个人的排名。AC代码#include <stdio.h>#include <map>#include <math.h>#include <string>#include <string.h>using namespace std;map<string, int> Rank;map<string, int> asked;const int maxn原创 2017-08-05 10:00:47 · 362 阅读 · 0 评论 -
PAT1117. Eddington Number
思路:搞懂题意是关键–E满足有共有E天骑车的距离超过E米,求最大的E! 将数组排序,我们假设最大的E是e,e满足条件有e天骑车超过e米,并且e+1不满足有e+1天骑车超过e+1米。那么我们可以逆序统计所有满足a[i]>n−ia[i] > n-i的就是答案。AC代码#include <stdio.h>#include <algorithm> using namespace std;const原创 2017-08-05 10:09:27 · 334 阅读 · 0 评论 -
PAT 1002. A+B for Polynomials
思路:就是两个多项式做加法–指数相同的相加即可,输出的时候按照指数递减输出,并且系数为0的项不输出。AC代码#include <stdio.h>#include <vector>#include <algorithm>using namespace std;const int maxn = 1000+5;float a[maxn];vector<pair<int, float> > an原创 2017-08-04 12:38:52 · 312 阅读 · 0 评论 -
PAT 1003. Emergency 单源最短路
思路:定义ways[i]ways[i]表示到达i的最短路径数量,d[i]d[i]表示到达i的最短径,cnt[i]cnt[i]表示最短路径到达i的最多人数,w[i][j]w[i][j]表示从i到j的距离, team[i]team[i]表示i点的人数。每次从u去更新某个节点v的时候,考虑两种情况: 1、d[v]>d[u]+w[u][v]d[v] > d[u] + w[u][v],说明到达v新的最短路径原创 2017-08-04 16:00:32 · 474 阅读 · 0 评论 -
PAT1001 A+B Format
思路:每三位分割,注意符号,首位不要出现逗号。AC代码#include <stdio.h>#include <algorithm>using namespace std;void solve(int c) { if(c < 0) printf("-"); c = abs(c); int dig[20]; int len = 1; do{ d原创 2017-08-04 12:04:19 · 512 阅读 · 0 评论 -
PAT1078 Hashing 坑爹
思路:用筛法给素数打表,二次探测法(只需要增加的)–如果hash(key)hash(key)的位置被占,那么就依次探测hash(key+1∗1),hash(key+2∗2)....hash(key+(size−1)∗(size−1)hash(key+1*1),hash(key+2*2)....hash(key+(size-1)*(size-1)。 注意:如果输入的MSize<=1MSize <=1原创 2017-08-04 11:38:04 · 1120 阅读 · 1 评论 -
PAT甲级 1004 树
思路:直接遍历整棵树判定每个结点是否有孩子,没有则把当前高度的叶子节点数加一。AC代码#include <stdio.h>#include <string.h>#include <algorithm>#include <vector>using namespace std;const int maxn = 100+5;vector<int> G[maxn];int level[maxn原创 2017-08-04 09:42:06 · 528 阅读 · 0 评论 -
PAT乙级1065 map
思路:检查某个客人是否有伴侣,如果有,伴侣是否也出现即可。 注意:0个单身狗的时候,不要输出多余的’\n’, 否则会出现格式错误。AC代码#include <stdio.h>#include <string.h>#include <map>#include <string>#include <algorithm>#include <vector>#include <iostream>原创 2017-08-04 09:08:35 · 259 阅读 · 0 评论 -
PAT乙级 1034
思路:是个水题,但是有坑。不能被题目忽悠了,题目保证正确的输出中没有超过整型范围的整数。 它只是保证结果不超出int,但是我们在运算过程中的乘法可能会超出int,直接把所有int改成long longAC代码#include <stdio.h>#include <algorithm>using namespace std;typedef long long LL;LL a, b, c, d;原创 2017-08-04 07:45:07 · 1255 阅读 · 0 评论 -
hihoCoder 树结构判定(并查集)
思路:树满足两个条件: 1、顶点数等于边数加一 2、所有的顶点在一个联通块 那么直接dfs或者并查集就可以了。AC代码#include <stdio.h>#include<string.h>const int maxn = 500+5;int par[maxn];int T, n, m;void init() { for(int i = 0; i <= n; i++) {原创 2017-08-01 09:47:02 · 585 阅读 · 0 评论 -
hihoCoder1319 岛屿周长 (bfs)
思路:从给定坐标开始bfs,将所有联通点标记,然后把每个联通点的四个方向都判断一下,如果这个方向相邻的是一个非联通点说明需要把这条边实在最外围,即周长的一部分。AC代码#include <stdio.h>#include <string.h>#include <vector>#include <algorithm>#include <map>using namespace std;#de原创 2017-08-01 09:21:52 · 591 阅读 · 0 评论 -
hihoCoder1310 岛屿 (dfs)
思路:首先dfs求得所有联通块,再搜索的同时把每个联通块的坐标都保存下来,然后把每个联通块处理一下–首先得到某个联通块的最小横坐标和纵坐标,然后让每个坐标去减去这个横坐标和纵坐标。相当于使得所有联通块都位于左上角了,然后再对坐标按照x和y排序就可以保证相同的联通块的所有坐标都一致。 后来想了一下,其实可以不排序,因为我们都是两层循环枚举一个点来进行扩展的,如果两个联通块(岛屿)形状一致,那么每次开原创 2017-08-01 09:38:54 · 566 阅读 · 0 评论 -
UVA - 11235 Frequent values(RMQ)
思路:除了考虑划分成的两段之外,还应该考虑两段的连接处的,因为可能出现连续的却被分成两截的情况。AC代码#include <stdio.h>#include <algorithm>#include <map>using namespace std;#define inf 0x3f3f3f3fconst int maxn = 1e5 + 5;const int W = 1e5; int原创 2017-07-31 15:36:44 · 264 阅读 · 0 评论 -
UVALive - 3027 Corporative Network (并查集)
这题比较简单,注意路径压缩即可。AC代码//#define LOCAL#include <stdio.h>#include <algorithm>using namespace std;const int maxn = 20000+5;int par[maxn], dis[maxn];void init(int n) { for(int i = 0; i <= n; i++) {原创 2017-07-29 14:24:34 · 448 阅读 · 0 评论 -
UVALive - 4329 Ping pong 树状数组
这题不是一眼题,值得做。 思路: 假设第ii个选手作为裁判,定义left[i]left[i]表示在裁判左边的[0,i−1][0, i-1]中的能力值小于他的人数,right[i]right[i]表示裁判右边的[0,i−1][0, i-1]中的能力值小于他的人数,那么可以组织left[i]∗(n−1−i−right[i])+right[i]∗(i−left[i])left[i] * (n-原创 2017-07-29 14:18:07 · 559 阅读 · 0 评论 -
UVALive - 3644 X-Plosives (并查集)
思路:每一个product都可以作一条边,每次添加一条边,如果这边的加入使得某个集合构成环,就应该refuse,那么就用并查集来判断。AC代码://#define LOCAL#include <stdio.h>#include <string.h>const int maxn = 1e5 + 5;int par[maxn], rank[maxn];void init() { mems原创 2017-07-27 13:55:50 · 383 阅读 · 0 评论 -
UVA - 11997 K Smallest Sums
数据结构原创 2017-07-27 11:16:09 · 383 阅读 · 0 评论 -
UVA - 11991 Easy Problem from Rujia Liu?
数据结构原创 2017-07-26 14:15:30 · 380 阅读 · 0 评论 -
UVA-673 括号匹配--栈
如果是一个合法的序列,每对配对的括号的两个字符(‘(’ 和 ')' 或者 '[' 和 ']')一定是相邻的,每次判断下该字符是否有配对即可。 如果配对,将左括号出栈即可。特别注意:空格也是合法的。AC代码:#include#includeusing namespace std;const int maxn = 200;char str[maxn];stacks原创 2017-02-03 16:32:16 · 110 阅读 · 0 评论 -
UVA - 11995 I Can Guess the Data Structure!(模拟)
数据结构原创 2017-07-26 13:21:14 · 469 阅读 · 0 评论