![](https://img-blog.csdnimg.cn/20201014180756724.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
算法竞赛
文章平均质量分 69
lzw_java
LeanCloud工程师
展开
-
2014年1月14日训练赛D题题解(栈+dfs)
题目:给出两个字符串s1和s2,如果s1能够通过栈的模拟得到s2,则输出详细的步骤,并且输出所有的可性操作。这里用'i'表示Push(进栈,插入一个元素),用'o'表示Pop(退栈,删除一个元素)。比如s1="TROT", s2="TORT",则可以有以下两种操作:i i i i o o o o和i o i i o o i o。先部署好一切:stack为模拟的栈原创 2014-01-14 15:39:49 · 1176 阅读 · 0 评论 -
排序新风格——归并排序
分治算法风格#include#include#includevoid merge_sort(int *A,int x,int y,int *T){ if(y-x>1)//只有一个元素排个毛 { int m=x+(y-x)/2;//划分成[x,m),[m,y),无论是有偶数个元素,还是有奇数个元素, merge_sort(A,x,m,T); //始终划分成第一个原创 2012-04-09 18:14:03 · 740 阅读 · 0 评论 -
快速排序中的算法艺术
先给出个人认为在众多由不同的划分过程导致的各种快排算法中最高效简洁的算法:void Qsort(int *A,int x,int y){ if(x>=y) return; int p=x,q=y,m=A[x]; do { while(A[p]<m) p++; while(A[q]>m) q--; if(p<=q) swap(&A[p++],&A[q--]); }原创 2012-04-14 22:21:54 · 699 阅读 · 0 评论 -
范围统计
//旨在明白求上界和下界的原理的情况下,熟悉STL算法中的lower_bound和upper_bound函数的用法 #include#includeusing namespace std;const int maxn=1000;int A[maxn];int main(){#ifndef ONLINE_JUDGE freopen("in.txt","r",stdin);原创 2012-04-21 09:35:19 · 766 阅读 · 0 评论 -
非线性方程求根
/*假设本金为2000元,分2个月还,每个月还1100,月利率为x,则(2000(1+x)-c)(1+x)-c=0,令f(x)=(2000(1+x)-c)(1+x)-c,当f(x)>0时,说明月利率太高了;当f(x)=0时说明月利率正确;当f(x)<0时,月利率过低。结果要求输出三位小数。 */#include#include#includeconst int maxn=1000;原创 2012-04-22 13:32:05 · 1114 阅读 · 0 评论 -
最大值最小化
//目标学会用猜数字(二分)的方法,换个角度来解决问题 #include#include#includeconst int maxn=100000;int A[maxn],n,m,max;void input(){ scanf("%d%d",&n,&m); max=0; for(int i=0;i<n;i++) { scanf("%d",&A[i]); max>原创 2012-04-22 14:17:40 · 2648 阅读 · 0 评论 -
noip2012 阅读程序1
#include#include#include#include#include#include#includeusing namespace std;const int maxn=1000;int n,i,temp,sum,a[100];int main(){#ifndef ONLINE_JUDGE freopen("in.txt","r",stdin);#endi原创 2012-10-13 19:29:34 · 738 阅读 · 0 评论 -
noip2012 阅读程序3
#include#include#include#include#include#include#includeusing namespace std;const int SIZE=20;int data[SIZE];int n,i,h,ans;void merge(){ data[h-1]+=data[h]; h--; ans++;}int main()原创 2012-10-13 19:31:00 · 866 阅读 · 0 评论 -
noip2012 阅读程序4
#include#include#include#include#include#include#includeusing namespace std;const int maxn=1000;int lefts[20],rights[20],father[20];string s1,s2,s3;int n,ans;void calc(int x,int dep){ a原创 2012-10-13 19:31:39 · 955 阅读 · 0 评论 -
从usaco hamming Codes谈FP思想及FP技巧
给一个自我感觉写得很不错,很Funtioanl Programming的代码,好处在于更结构化了,让main成为Lisp等函数式编程语言中的Top-level。……这样的话,我就不用新建一个cpp,来试探一下自己不熟悉的函数或者是调试某个独立的函数。直接把deal()注释掉,然后把main函数当成Top Level,当成RPEL,read-print-eval-loop。Lisp教给我的还有尽可能地函数式编程,FP!这样每个函数都可以单独提取出来调试。语义也更加清晰。原创 2013-11-11 00:08:11 · 1608 阅读 · 0 评论 -
回文数多还是质数多,谈USACO回文质数题Prime Palindromes
用isPrime(i)&&palindrome(i)作为判断语句的话,输出1亿以内的全部回文质数,要35秒,而用palindrome(i)&&isPrime(i),只用19秒!……有趣的是,打表的时候发现,除了11,没有偶位数的回文质数!采用直接构造回文数再判断是否为质数的方法更快,而且只用构造奇数位的回文数,像这样求出所有构造所有n位数的回文数。原创 2013-11-07 14:18:51 · 1460 阅读 · 0 评论 -
uva 101 the blocks problem
uva老不让过……注意:move a onto bwhere a and b areblock numbers, puts block a onto block b afterreturning any blocks that are stacked on top of blocks a and b to their initial positions.原创 2012-01-07 14:01:20 · 783 阅读 · 0 评论 -
noip2012 阅读程序2
#include#include#include#include#include#include#includeusing namespace std;const int maxn=1000;int n,ans;int gcd(int a,int b){ if(a%b==0) return b; else return gcd(b,a%b);}int main()原创 2012-10-13 19:30:19 · 722 阅读 · 0 评论 -
uva 10003 - Cutting Sticks 动态规划
题目换一个思路,剪不好处理,拼接怎么样?这就转化成了“合并石子”的问题。有n堆石子,排成一列,每次可以将相邻两堆合并,合并的费用为合并后得到新的一堆石子的石子数,将所有石子合并成一堆,求最小的合并费用。那这题怎么写对拍呢?给出木棍的范围[a,b),找出这段范围内可以剪的位置,枚举剪的位置,转化为另一个规模较小的子问题,这又可以用动态规划来做。但是其复杂度是O(N*I*I),I为木棍的最大长原创 2012-10-21 11:59:20 · 1004 阅读 · 0 评论 -
uva 116 - Unidirectional TSP(精心设计的测试数据)
题目题目大意是说,一个数字矩阵,从第1列到最后一列,一步可以往右走、右上走、右下走。路权为这条路径上的数字之和。输出最小路权及字典序最小的路径。这题的一大亮点是,如果采用遍历每条路径从而获得字典序最小的路径的话,必然会超时;或者要加上剪枝才能通过检测,但是我没有找到强有力的剪枝。求神牛指点。正确的做法是从后往前转移状态,假如当前往右、右上、右下都一样最优,则选择右上,每一步都这样做,必原创 2012-10-21 16:20:05 · 1349 阅读 · 0 评论 -
uva 146 - ID Codes
原题 如果出题人知道有Next_permutation这个函数,估计他就会放弃这个尽管有着这么丰富背景的题了。#include#include#includeusing namespace std;int main(){#ifndef ONLINE_JUDGE freopen("146.txt","r",stdin);#endif char s[60]; while原创 2012-02-09 18:24:01 · 695 阅读 · 0 评论 -
uva 131 - The Psychic Poker Player
参考题解 原题 子集生成的问题。用增量构造法。需要先弄清楚规则。特殊的顺子有两种,TJQKA和A2345。#include#include#includeusing namespace std;const int maxn=15;char *sf="A23456789TJQK";char *su="CDHS";char str[9][20]={"straight-f原创 2012-02-11 21:59:10 · 882 阅读 · 0 评论 -
uva 729 - The Hamming Distance Problem 枚举排列
参考《算法竞赛入门经典》,用递归枚举时。枚举排列时,到cur==n,即够n个元素的时候,才终止递归。枚举子集,则枚举到0-n个元素都要进行操作。一:#include#include#includeconst int maxn=20;int P[]={0,1};int A[maxn];void print_permutation(int n,int h,int *A,i原创 2012-02-14 17:55:19 · 874 阅读 · 0 评论 -
uva 196 - Spreadsheet
原题下面有非常高效的代码。这题给出的A……ZZZ共18278列是纸老虎,这只老虎很吓人,老是诱惑人走进超时的怪圈。实则开一个1001*1001的数组就足矣。两个方法,一个是用简单的topo排序一下。另外一个是,链表处理。如D1这个格子,D1=A1+B1+C1。那么在A1,B1,C1三个单元格的出度指向域中保存D1,便可从A1,B1,C1出发,搜索到D1,便把当前的单元格值加到D1的单元格值上,原创 2012-02-17 18:09:54 · 1522 阅读 · 1 评论 -
tyvj 1111 舞会 用kosaruju算法求强联通分量的个数
http://new.tyvj.cn/Problem_Show.aspx?id=1111//kosaruju算法,强连通量个数 #include#include#include#include#include#include#include#includeusing namespace std;const int maxn=201;vectorG[maxn],Gt[max原创 2012-10-16 14:09:58 · 1294 阅读 · 0 评论 -
uva 674 - Coin Change(动态规划)
题目算法:用f(i,s)表示使用前i种硬币来凑s分钱的方法数。考虑第i种硬币的使用情况,它当然可以不用,也可以用1张,2张……直到再用一张就超过s分钱为止。f(i,s)=f(i-1,s-k*v[i]),0s=0时,f(i,s)=1。i=0但s!=0时,f(i,s)=0。 因为硬币的种类是知道的,要凑的钱的范围也是提前可知的,且比较小,而且要回答多个询问,因此可原创 2012-10-21 09:47:47 · 1005 阅读 · 0 评论 -
uva 10047 - The Monocycle
如果最后要求最短的时间,那么每一秒所在的状态为一个状态,这一秒可以引发的下一个状态再进入队列,每次取出队列的队首元素进行操作即可。#include#include#includeconst int maxn=30,maxm=18000;//18000=maxn*maxn*5*4 struct Point{ int x,y,c,d;//c=color green=0,black=1原创 2012-02-03 12:36:26 · 719 阅读 · 0 评论 -
uva 532 - Dungeon Master
方法一:结构体中增加一个记录时间的项。方法二:增加一个数组int dist[maxn][maxn][maxn];记录距离。每一个单位的距离就为一个单位的时间。因此结果照样输入即可。方法都差不多,评测结果却显示方法二要更快,为什么更快呢?还是评测结果的误差?求教。一:#include#include#includeconst int maxn=40;struct Point原创 2012-01-23 16:14:30 · 619 阅读 · 0 评论 -
uva 10557 - XYZZY 关键词:正环,无敌bfs,单源最短路spfa算法
笔者用时:4h。方法一:当发现有个和为正值的环存在时,直接求看该点能否直接到达终点。如果可以,直接返回true,即winnable。否则,不用做任何的标记。因为不会再去探索它是否可以直接到达终点。这个方法效率很高。rank:7。在搜索的过程中看看有没有正环,没有正环则继续搜索,当发现所有路径都不能到达终点时,返回假值。方法二:要低效一点。rank:300左右。用的spfa。用最后一组给的样原创 2012-01-26 17:32:52 · 3258 阅读 · 2 评论 -
uva 439 - Knight Moves
方法一:不用预处理。方法二:预处理,查表。#include#include#includeconst int maxn=70;int dir[8][2]={{-1,-2},{-1,2},{-2,-1},{-2,1}, {1,-2},{1,2},{2,-1},{2,1}};struct Point { int x,y,n;//n steps};Point q[ma原创 2012-01-22 10:37:33 · 547 阅读 · 0 评论 -
uva 705 - Slash Maze
方法一(放大两倍):for(j=0;jif(s[j]=='\\') mat[2*i][2*j]=mat[2*i+1][2*j+1]=1;else mat[2*i+1][2*j]=mat[2*i][2*j+1]=1;把下图放大两倍。得到以下表格。@表示有斜线,空白处表示无斜线。染色部分表示路径。结合另外一位大牛的题解来看。另外,考虑这点可不可以往右下走原创 2012-01-21 12:50:10 · 703 阅读 · 0 评论 -
uva 11111 - Generalized Matrioshkas
两解决方案。注意把数组开大点,能装下10000个元素是保险的。(1)#include#includeconst int maxn=10000;char s[maxn*3];int A[maxn],stack[maxn],top,n;int is_ok(){ int i; top=0; for(i=0;i<n;i++) { if(A[i]<0) stac原创 2012-01-09 18:09:36 · 563 阅读 · 0 评论 -
uva 673 - Parentheses Balance
#include#includeconst int maxn=130;char A[maxn],s[maxn];int top;int main(){#ifndef ONLINE_JUDGE freopen("673.txt","r",stdin);#endif int n; scanf("%d\n",&n); while(n--) { top=0; fgets原创 2012-01-07 19:13:50 · 452 阅读 · 0 评论 -
uva 208 - Firetruck
原题并不是所有的顶点都可以到达火灾现场,要从火灾现场开始遍历,找出可以到达火灾现场的所有顶点。再在这些顶点进行搜索。另外,快排中,是取中点的元素,将数组分成两半,左边的都小于这个元素,右边的都大于这个元素。比较的时候是while(A[i]#include#include#includeconst int maxn=25;int n,end,A[maxn],top,tot原创 2012-03-17 12:52:28 · 652 阅读 · 0 评论 -
uva 301 - Transportation 一切都是那么暴力
原题 回溯后要把数据改回来。#include#include#includeint n,b,m,A[25][3],cap[8],max;int try1(int u){ int i; for(i=A[u][0];i<A[u][1];i++) { cap[i]+=A[u][2]; if(cap[i]>n) return 0; } return 1;}原创 2012-02-25 22:39:37 · 818 阅读 · 0 评论 -
uva 539 - The Settlers of Catan
原题人类失去搜索,世界将会怎样?难以想象……#include#include#includeconst int maxn=30;int G[maxn][maxn],vis[maxn][maxn],n,max;void search(int u,int s){ if(max<s) max=s; for(int v=0;v<n;v++) if(G[u][v] && !vis原创 2012-02-25 18:49:51 · 623 阅读 · 0 评论 -
uva 10004 - Bicoloring
这题还真太简单了……不过我的方法效率有点低。改天要去看看大牛怎么做。bfs:#include#include#includeconst int maxn=210;bool G[maxn][maxn],vis[maxn],color[maxn];int n;int q[maxn*maxn];bool bfs(){ int front=0,rear=0; q[r原创 2012-02-03 13:28:19 · 545 阅读 · 0 评论 -
uva 10129 - Play on Words
需要了解几个知识:并查集(见《算法竞赛入门经典》第11章。)把26个字母当做节点,每个单词表示一条边。用这样的方式建图,比较入度与出度的大小关系即可。见《算法竞赛入门经典》第六章欧拉回路相关知识。另外,如果读取的字符数组开的不够大,会引起runtime error错误。#include#include#includeconst int maxn=1010,maxm=30;char s原创 2012-02-03 19:09:17 · 1259 阅读 · 1 评论 -
uva 10054 - The Necklace
用并查集判断所有珠子是否在同一个连通分量。如果并查集不懂的话,请参考:http://blog.csdn.net/lzw_java/article/details/7232287珠子有范围,先用max,min记录其最大最小值,后来在dfs下才能限定范围,而不总是在1到50里搜索。这样做,总是好的。#include#include#include#define INF 1<<30c原创 2012-02-04 12:46:27 · 924 阅读 · 0 评论 -
uva 10305 - Ordering Tasks
题目大意:任务排序。有些任务之间有先后顺序。拓扑排序。如果有多个连通分量,那么把每个连通分量遍历完,加入topo数组,最后输出即可。代码一:先判断是否可以拓扑排序。代码二:上来就拓扑排序。代码一:#include#include#includeconst int maxn=110;int topo[maxn],t,n,c[maxn];bool G[maxn][ma原创 2012-02-04 13:35:42 · 846 阅读 · 0 评论 -
埃及分数
参考《算法竞赛入门经典》p130的分析。迭代加深搜索。原题:在古埃及,人们使用单位分数和(形如1/a的,a是自然数)表示一切有理数,如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中不允许有相同的。对于一个分数a/b,表示方法有很多种,其中加数少的比加数多的好,如果加数个数相同,则最小的分数越大越好。例如:19/45=1/3+1/15+1/45=1/3+1/18+1/3原创 2012-02-12 18:18:38 · 1431 阅读 · 0 评论 -
10474 - Where is the Marble? 有技巧地快速查找
原题提供三个代码。效率由高到低。当我认为二分的效率已经够高时,我看到了他的文章,又把效率提高了。链接#include#include#includeconst int maxn=20000;int be[maxn],pos[maxn];int main(){#ifndef ONLINE_JUDGE freopen("10474.txt","r",stdin);#e原创 2012-02-22 18:13:56 · 649 阅读 · 0 评论 -
uva 110 - Meta-Loopless Sorts
原题从n个数的当前排列,得到n+1个数的排列,可以这样。设有排列a,b(a插入c,可以得到三个排列a如果已经确定a那么比较b否则有b>c,此时比较ac,可以得到排列a否则有a>c,此时,c把第n+1个需要比较的数插入原来n个数的排列,有n+1种方法,也即把n个数隔开写,得到n+1个空位置,每一个位置的插入得到一个新的排列。#include#incl原创 2012-02-24 21:47:42 · 781 阅读 · 0 评论 -
uva 639 - Don't Get Rooked
原题这题比起八皇后问题更复杂。有两种状态转移方式:直接进入下一行搜索;在这一行选一个,仍在这一行搜索。#include#include#includestruct Pos{ int x,y;};Pos C[16];int n,max,mat[6][6],vis[6][6];int is_capture(int x,int y,int s){ int i,j,ok原创 2012-02-25 18:32:42 · 661 阅读 · 0 评论 -
IOI 94 The Clock 详细的总结,从指数级复杂度到常数时间的优化
原题如果用bfs的话,也即,把操作顺序的先后考虑上的话,那么要注意用hash表来判重,用空间换时间。这个低效的方法也是能过的……//hash表判重,dfs,从短到长按字典序扩展操作序列的长度 /*{ID: lzwjava1PROG: clocksLANG: C++}*/#include#include#include#include#includeusing原创 2012-11-09 18:28:50 · 1516 阅读 · 0 评论