摘要:
让我们求的是最少的ai>aj数。看到题目是没啥思路。。。在网上搜了一下,有暴力的,有线段树的。 暴力的比较简洁,也很容易弄懂,代码如下:#include <iostream>using namespace std;int s[5001];int main(){ int i,j,n,m,a; while(cin>>n) { for(m=i=0;i<n;i++) for(cin>>s[i],j=0;j<i;j++) if(s[j]>s[i]) m++; a=... 阅读全文
摘要:
直接求超时。用线段树。简单做法直接用2N数组,以1为root,2*i为左节点,2*i+1为右节点。 求区间[a,b]和时,如果a为右节点,则减去左节点的值。如果b为左节点,则减去右节点的值。a,b迭代为自己的父母。当a,b相等时,加上当前节点的值,即为区间和。 我也是第一次接触线段树的概念。刚开始也想自己建立一棵树。在网上找到了张昆玮的线段树的讲稿,才发现可以直接用数组。分享下:http://wenku.baidu.com/view/f27db60ee87101f69e319544.html#include <iostream>using namespace std;int s[1 阅读全文
摘要:
初看以为很简单的。。。当然,直接数组保存单词然后遍历查询一定会超时。在网上搜索了一下,看到“字典树”的概念。自己也没看他的代码,但是却找到了方法了。 字母一共有26个。建立一个结构,里面保存一个大小为26的指针数组,然后读入单词,节点+1。额,看代码更清楚些#include <iostream>#include <string>using namespace std;class word{public: word() { memset(s,0,sizeof(s)); num=0; } word *s[26]; int num;};... 阅读全文
摘要:
无奈的Wrong了N次,请教师兄后才搞定这题。。。注意消空格,用STL里的set做的,代码如下:#include <iostream>#include <set>#include <string>using namespace std;int main(){ set<string> st; char str[1000]; char s[100]; int len,slen; while (cin.getline(str,sizeof(str)) && str[0]!='#') { st.clear(); len=0 阅读全文
摘要:
表面上看是回溯+深搜,直接做的话会超时。 在搜索前判断,给定的步数是否小于理论最短长度,并且他们的差是否是2的倍数(画图易知)。 AC代码如下,时效比较差,406MS。看到有0MS的,看来还是得好好学习呀。#include <iostream>using namespace std;int m,n,a,b,t,s[10][10],flag,dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}};void DFS(int x,int y){ int i,j,k; if(t==0) { if(x==a && y==b) ... 阅读全文
摘要:
回溯法,经典题啊。发现很简单有木有。。。看代码~用数组保存sum值,否则会超时。杭电也够坑人的。。。#include <iostream>using namespace std;int col[11],dia[21],evil[21];int n,sum,s[11];void DFS(int x){ int i; if(x==n+1) { sum++; return; } for(i=1;i<=n;i++) { if(!col[i] && !dia[x+i] && !evil[10+i-x]) { ... 阅读全文
摘要:
素数环,回溯法,DFS基础题。对于DFS偶还没接触过,看到一篇好的文章,分享下:http://yangjunke111.blog.163.com/blog/static/135279606201041312753102/ 额,直接看代码吧#include <iostream>using namespace std;int n,cas=1,visit[20],result[20]={0,1},p[]={0,0,1,1,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0};void DFS( 阅读全文
摘要:
搜索。泡泡龙游戏,难点在于那些掉下去而爆炸的泡泡。刚开始一直报错报错,搞不明白。在网上找到一份AC的代码,发现思路是一样的,都是先把泡泡消掉,从第一行开始深搜。重新写了代码,如下:#include <iostream>#include <deque>using namespace std;struct point{ int x,y;} x,y;deque<point> q;int dir[6][2]={-1,1,0,2,1,1,1,-1,0,-2,-1,-1},sum;char mat[205][205];int bfs(int a,int b,char c 阅读全文
摘要:
搜索,bfs。依旧用队列做。边界处懒得处理,全部初始化为-1。当然,0也可以。AC代码如下:#include<iostream>#include<deque>using namespace std;struct Point{ int x,y;} x,y;int main(){ char str[22]; int i,j,n,m,s[22][22],t; deque<Point> q; while(cin>>m>>n && (m||n)) { q.clear(); memset(s,-1,sizeof(s)); f... 阅读全文
摘要:
马走棋盘,搜索。刚开始想打表,发现棋子在边界的时候很难处理,比如a1到b2的话2步是不行的。 用队列,时效差一点点,46MS,代码如下:#include<iostream>#include<deque>using namespace std;struct Point{ char x,y,num;};int main(){ int a,b,i,j; Point x,y; deque<Point> q; char str[2],str2[2]; char visit[8][8]; while(cin>>str>>str2) { m... 阅读全文
摘要:
搜索,广度优先。 之前使用的遍历超时了,没办法,学习了队列的写法。以下代码源自网上,改了一点,AC#include<iostream>#include<deque>using namespace std;int main(){ int i,a,b,n,x,y,s[201],t[201]; deque<int> q; while(cin>>n && n) { q.clear(); memset(t,0,sizeof(t)); cin>>a>>b; for(i=1;i<=n;i++) cin... 阅读全文
摘要:
题意差不多就是天使的朋友去就天使。刚开始从r开始遍历,步数依次+1,遇x则+2,但是一直报错。 然后笔者就一直在网上找呀。。。一般都是bfs,优先队列,栈啥的。代码看起来就很复杂,笔者也懒得看了。但是从a到r的逆向思想却还是有用的。 改代码,只用数组,AC了。如下:#include <iostream>using namespace std;int s[202][202];int main(){ int i,j,t,n,m,flag; char str[202]; while(cin>>n>>m) { for(i=1;i<=n;i++) ... 阅读全文
摘要:
广搜。看代码~#include <iostream>using namespace std;char s[102][102];void visit(int a,int b){ s[a][b]=0; int i,j; for(i=a-1;i<=a+1;i++) for(j=b-1;j<=b+1;j++) if(s[i][j]==-1) visit(i,j);}int main(){ int i,j,m,n,t; char str[102]; while(cin>>m>>n && (m||n)... 阅读全文
摘要:
题意基本是说空间中有小行星阻挡,你要从起点移动到终点,每次移动一个单位,求最短路径。 因为刚刚接触图论,乍一看以为要深搜或者广搜啥的。仔细想想之后,发现还是蛮容易的。 因为题目上的坐标包括0,不好做边界处理,索性都+1。 小行星处记为-1,在起点处记为1,步数t记为1。然后遍历吧,发现和步数一致的点时判断上下左右前后六个点是否是初始化时的0状态,是的话赋值t+1,即代表t+1步时可以到达此点。遍历前判断终点处的值是否大于0了,大于的话退出循环。然后如果遍历一遍没有找到与步数t一致的点,退出循环,测试也过了,但是可以不写。 因为起点为方便处理记为1,所以最终的答案减去1。 下面是A... 阅读全文
摘要:
好玩的题。ABCD四点,三分法嵌套三分法。看代码应该更清晰一点~#include<iostream>#include<cmath>using namespace std;const double eps=1e-7;double p,q,r;struct Point{ double x,y;} A,B,C,D;double getDistance(Point a,Point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double cToD(Point a){ Point midl,midr; P.. 阅读全文
摘要:
题目偶不说了,贴代码:#include<iostream>using namespace std;int main(){ double temp,eps=1e-7; int i,sum,max,low,high,mid,ans,n,k,s[10001]; while(cin>>n>>k && (n||k)) { sum=max=0; for(i=0;i<n;i++) { cin>>temp; s[i]=(int)((temp+eps)*100); if(max... 阅读全文
摘要:
将所有的点转化为x-z平面上,求使所有的点在直线x/r+z/h=1的下方,且使r*r*h最小的h与r的值。 依然使用三分法。可以这么多点,如何处理呢? 笔者首先选取x坐标最大的点,使直线过此点,逆时针旋转至下一个点,三分求体积最小值。再使以下一点逆时针旋转,直至没有点或者直线斜率k>=0。这样每次所有的点都在直线下方。AC代码如下:#include<iostream>#include<cmath>using namespace std;double pi=acos(-1.0);double eps=1e-9;double fun(double x,double y 阅读全文
摘要:
解题报告:自己画个图,可知,在y>=max(w/sin(a)+l*cos(a)-x/tan(a))(0<=a<=90)时,汽车可以通过,否则不可通过。 对于这种函数,可以使用三分法,求最大值。笔者比较懒。。。直接暴力,代码如下:#include<iostream>#include<cmath>using namespace std;int main(){ int i=0; double x,y,l,w; double PI=acos(-1.0)/20000; while(cin>>x>>y>>l>>w) 阅读全文
摘要:
几何题,求圆锥体积差不多的题,难度不大,要注意的是杯子口半径R>=杯底半径r。下面是笔者的代码,AC了#include <stdio.h>#include <math.h>int main(){ int c; double r,R,H,V,t,P=acos(-1.0); scanf("%d",&c); while(c--) { scanf("%lf%lf%lf%lf",&r,&R,&H,&V); if(R==r) t=V/(R*R*P); else { t=H*... 阅读全文
摘要:
分组背包的问题,挺巧妙的。推荐看一下背包九讲的第六讲:分组的背包问题。额,我贴在下面吧,当然这是大牛写的。下面的是AC代码:#include <iostream>using namespace std;const int MAX=110;int dp[MAX];int c[MAX][MAX];int main(){ int m,n,i,j,k; while(cin>>n>>m && (m||n) ) { memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) for(j=1;j<=m;j++)... 阅读全文
摘要:
01背包问题的变形题,很简单了,下面是偶的AC代码。初始化是全部赋值为1,即100%。memset函数是不行的哦。#include <iostream>using namespace std;const int MAX=10001;int c[MAX];double dp[MAX];double v[MAX];int main(){ int n,m,i,j; double t; while(cin>>n>>m && (n||m)) { for(i=0;i<m;i++) { cin>>c[i]>>t; ... 阅读全文
摘要:
题目不难。背包问题,上限是总和的一半。可以转化成01背包问题,也可以用多重背包解决。下面是笔者的AC代码:#include <iostream>using namespace std;char dp[250001];int v[51];int m[101];int main(){ int i,j,k,n,max,t,sum; while(cin>>n) { if(n<0) continue; for(sum=i=0;i<n;i++) { cin>>v[i]>>m[i]; ... 阅读全文
摘要:
哈哈,今天是过年哦,祝大家 新年快乐~ 看这题吧,乍一看这题是01背包问题。看看这N和C的范围,用01背包做的话,Time Limit Exceeded。 网上百度了一下,找到了解决方法。因为0≤Vi,Ci≤10,所以可以进行优化。即在V-10的范围内,直接选择性价比高的单词,后者使用01背包优化。至于问什么可以这么做,我只是觉得很合理,具体的证明我还得找找。#include<iostream>#include<algorithm>using namespace std;int dp[10001];char str[20];struct s{ int c,v;} w[1 阅读全文
摘要:
很有趣的一道题。简单分析一下可知: (1)如果所有的菜的总金额sum小于等于卡上金额value-5,我们可以购买所有的菜,并且最终余额是value-sum。 (2)如果所有的菜,除去最贵的菜,的金额sum-max小于等于value-5,我们可以先购买其他的菜,最终卡上金额必大于等于5,最后购买那道最贵的菜,使总金额最低,并且最终余额也是是value-sum,可与(1)条件合并。 (3)如果卡上金额小于5,啥也买不了,直接输出吧。 (4)如果都不符合,那就进入最复杂的处理了。先购买适量的菜,使卡内余额的金额大于等于且最接近5,最后购买最贵的菜就好了。子问题也就是01背包问题。 额,... 阅读全文
摘要:
01背包问题。以前没有做过,也没学过,所以在百度上学习了一下,链接:http://baike.baidu.com/view/841810.htm AC代码如下:#include <iostream>using namespace std;const int MAXLEN=1010;int f[MAXLEN];int c[MAXLEN];int w[MAXLEN];int main(){ int n,v,i,j,cas; cin>>cas; while(cas--) { cin>>n>>v; memset(f,0,sizeof(f)); ... 阅读全文
摘要:
动态规划,简单题。 每次走,从(x,y)到(x+1,y)或(x,y+1)或(x,y*k)(k>1 && y*k<=m)。每次就有三种选择,而我们要选择令和最大的路径。 动态规划的原则,结果最优,则子结果也是最优的,对于每个位置(x,y),我们求最大值,即取(x-1,y),(x,y-1),(x,y/k)三个位置的最大值。(x-1,y),(x,y-1)很容易处理,对于(x,y/k),我们可以在处理每个位置后,对他的y整数倍位置进行赋值,比他大则更新。额。。。看代码更清楚。#include <iostream>using namespace std;int d 阅读全文
摘要:
数塔的变形体,额,这么一想就简单多了。。。第0秒 5第1秒 4 5 6第2秒 3 4 5 6 7第3秒 2 3 4 5 6 7 8第4秒 1 2 3 4 5 6 7 8 9第5秒 0 1 2 3 4 5 6 7 8 9 10第6秒 0 1 2 3 4 5 6 7 8 9 10... 和数塔相同的解法,自下而上,取较大值即可,下面是笔者的AC的代码:#include <iostream>using namespace std;int maxOfThree(int a,int b,... 阅读全文
摘要:
经典的题吧,最长公共子序列。 额,一开始想错了,总是超时。看了网上大牛的代码,恍然大悟。AC代码如下:#include <iostream>using namespace std;int dp[2013][2013];char a[2013],b[2013];int main(){ int i,j,lena,lenb; while(scanf("%s%s",a,b)!=EOF) { memset(dp,0,sizeof(dp)); lena=strlen(a); lenb=strlen(b); for(i=0;i<... 阅读全文
摘要:
动态规划,最大上升子序列和。不同的是给的是长方体。 为了方便处理,笔者直接将每个长方体当做三个长方体处理,每个长方体的长大于等于宽。然后以长为主,宽为辅排序。 然后就和之前的那道FatMouse‘s speed一样了,当符合条件是,更新最大值。 下面是笔者第一次AC的代码:#include <iostream>#include <algorithm>using namespace std;struct State{ int length; int width; int height; int sum;} s[100];int cmp(const State& . 阅读全文
摘要:
动态规划,最大上升子序列和。状态是每个位置的最大和,写出状态转移方程就好啦。和上一题FatMouse's Speed相似,而且简单一点。 下面是笔者的AC代码:#include <iostream>using namespace std;struct State{ int num; long long sum;} s[1001];int main(){ int i,j,n; long long max; while(cin>>n && n) { for(i=0;i<n;i++) { cin>>s[i].... 阅读全文
摘要:
动态规划,最长上升子序列。看代码吧,可能更容易懂。#include <iostream>#include <algorithm>using namespace std;struct State{ int id; int weight; int speed; int pre; int num;};bool cmp(const State &a, const State &b){ if(a.weight!=b.weight) return a.weight<b.weight; else return a.speed>b.sp... 阅读全文
摘要:
动态规划经典题,求和,大于max则更新,小于0则将和置为0,重新求和。 因为笔者没有系统学过动态规划,所以一开始也是不会的。在网上看了大牛的解法后,算是明白了。贴上AC代码,就容易理解了。#include <iostream>using namespace std;int main(){ int cas,cas2,i,n,sum,max,a,b,num,begin; cin>>cas; cas2=cas; while(cas--) { sum=a=b=0; begin=1; max=-1001; cin... 阅读全文
摘要:
动态规划经典题~直接贴代码,很容易理解应该。#include <iostream>using namespace std;int main(){ int s[101][101]; int cas; int i,j,n; cin>>cas; while(cas--) { cin>>n; for(i=0;i<n;i++) for(j=0;j<=i;j++) cin>>s[i][j]; for(i=n-2;i>=0;i--) for(j=0;j<... 阅读全文
摘要:
A了这一题,学了不少东西,说说。 首先,题意是计算a[L]%m的值。而a[1]=2,a[2]=4,a[3]=6,a[4]=9。L的范围比较夸张,[0,1000000]。 E-queues串的结尾必然是[1]:000,[2]:100,[3]:001,[4]:011,[5]:010,[6]:110 在长度为n-1的E-queues串加0或1,则 a[n][1]=a[n-1][1]+a[n-1][2] a[n][2]=a[n-1][5]+a[n-1][6] a[n][3]=a[n-1][1]+a[n-1][2] a[n][4]=a[n-1][3] a[n][5]=a[n-1][3] a... 阅读全文
摘要:
额,不是很喜欢这道题。。。失败了好几次,因为考虑的不详细。高进度乘法倒是没什么,吧前面的0和后面的0处理好即可。 下面是笔者的AC代码,比较难看,见谅。笔者自己也不想改了。。。==||。附带网上找到的测试数据。#include <iostream>using namespace std;const int MAX_LEN=1000;int temp[1000];void mul(char* z,char* x,char* y){ int lenx=strlen(x); int leny=strlen(y); int i,j; memset(temp,0,1000*... 阅读全文
摘要:
和前几天做的差不多的题目,1267那道,分析和那道差不多。要注意的是100!,longlong不够,继续使用以前的高精度类。 题目还有一个比较坑人的地方,没有告诉你m>=n,需要处理m<n的情况,就是直接输出个0。。。下面是笔者AC的代码,仅供参考#include <iostream>using namespace std;const int MAX_LEN=1000;int temp[MAX_LEN];class bigNumber{public: bigNumber() { memset(number,0,sizeof(number)); nu... 阅读全文
摘要:
看起来超级简单的题,除了那2005位数。。。正好这几天都在做高精度乘法和加法的题,自己写了一个类。 下面是我的AC代码:直接加的话内存会爆,所以我又特地写了一个函数,呵呵。。。7038的原因是strlen(t[7037])==2005.#include <iostream>using namespace std;const int MAX_LEN=2010;int temp[MAX_LEN];class bigNumber{public: bigNumber() { memset(number,0,sizeof(number)); number[0... 阅读全文
摘要:
这道题简单分析一下,发现考的还是catalan数和高精度乘法,和上一题做法是一样的,乘个阶乘就好了。 这是百度上对catalan的介绍~http://baike.baidu.com/view/1154333.htm 笔者的AC代码:可读性依旧很差,还是打算自己写个高精度类的,完成的话继续贴在上面。 另外,笔者的做题顺序是杭电上的ACM STEPS的顺序,初学者可以试试,题目是由易到难的,做做还是有好处的。#include<iostream>using namespace std;char s3[10000];char temp[10000];char N[4];void num(i 阅读全文
摘要:
题目本身不难,简单分析一下,就可以得出递推公式,然后写代码。下面的是我刚开始写的代码:#include <iostream>using namespace std;int main(){ int i,n; long long s[101]; memset(s,0,sizeof(s)); s[0]=s[1]=1; for(n=2;n<=100;n++) { for(i=1;i<=n/2;i++) { s[n]+=s[i-1]*s[n-i]; } s[n]*=2; i... 阅读全文
摘要:
题目很长,也很有趣~当然,题意就是假定一个字符串由m个H和n个D组成,从左到右扫描该串,字符H的累计数总是不小于字符D的累计数,求满足条件的字符串总数。 乍一看挺复杂,像是排列组合什么的。仔细想一想,可以简单的画一个图来解决。 以向右的箭头代表H,右下的箭头代表D,可以得到f(m,n)的表达式: f(m,n)= f(m-1,n),n=0 f(m,n-1),m==n f(m,n-1)+f(m-1,n),0<n<m 1,m=n=0 根据递推式写出代码即可。以下是笔者的AC代码:#include <iostream>using namespace... 阅读全文