2011年12月17日
摘要: 思路:其实很道路很水,显然如果增大的话是3的指数增大,所以即使n=10000,但是其实回归到1的时间也只是log的时间而已。所以可以直接暴力打表。写递归只是练习一下记忆化搜索。感觉DFS的基础真是不扎实。菜啊。最恶心的是给的数据范围有可能是坐边数字大于右边。因此wa了好多次。。#include<iostream> #define max(a,b) (a>b?a:b) using namespace std; const int N=10005; int data[N]; void dfs(int i,int k,int s) { if(i<N&&data 阅读全文
posted @ 2011-12-17 11:51 不是我干的 阅读(202) 评论(0) 推荐(0)
  2011年12月15日
摘要: 题意:给一串数字,里面只包含0 -1 1三种数字。问和为0的最长连续子串。思路:遍历一遍,求每个i的sum[i],代表从第一个数字到这个数字的和。显然如果sum[i]=sum[j],则从i+1到j这j-i个数字的和=0。即次数所求的D=j-i-1。#include<iostream> #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) using namespace std; const int N=50005; int n; int data[N]; int pos[N]; int neg[N]; int mx; 阅读全文
posted @ 2011-12-15 19:18 不是我干的 阅读(140) 评论(0) 推荐(0)
  2011年12月6日
摘要: 题意:给你一个二维坐标上的几个点,问在同一条直线上最多几个点。思路:N=700,刚开始我枚举两个点i,j。(两个点一条线),然后用k枚举一遍各个点。这样算出每条线上最多的点。用了O(N^3)的超时了。我真是太天真了。其实在枚举每个k的时候就可以想到。k明显有一些可以优化的地方。优化:之前是枚举每条线,现在是枚举每个点,对于每个点i,求i和其它所有点的斜率。找出斜率相同点的个数。(用hash空间承受不来),所有用sort(O(nLOGn))即可找出。所有现在是O(N^2*LOGN),200+ms。#include<iostream> #include<algorithm> 阅读全文
posted @ 2011-12-06 21:33 不是我干的 阅读(326) 评论(0) 推荐(0)
  2011年12月4日
摘要: 思路:查看了网上不少博客,感觉都写得很朦胧,都说从后往前插。这个倒好理解。但是很多都没说清楚为什么用线段树,用的思路。搞得我一头雾水。毕竟是刚接触线段树,对线段树理解也不够。今天晚上硬着头皮推敲。终于有点思路了。我的理解:就例子0 201 191 380 31从后往前插。首先是0 31.位置是精确的就是在第0位。然后是1 38.38想插在第1位。但是这是38一厢情愿,他能不能最终落在第1位,必须经过0 31的同意。即因为在1 38的操作后,0 31的操作会使1 38位置变动。怎么变动?很简单,就是往后退一位,使1 38的操作最终下场是38落在了位置1+1=2,第2位。说到这里是不是有点启发了。 阅读全文
posted @ 2011-12-04 13:20 不是我干的 阅读(207) 评论(0) 推荐(0)
  2011年12月3日
摘要: 题意:给你一个DNA的序列,给定逆序数的定义,叫你按逆序数从小到大排序输出。其实很简单。只不过为了排序,弄个结构体出来比较方便。#include<iostream> #include<queue> #define max(a,b) (a>b?a:b) #define min(a,b) (a<b?a:b) #include<algorithm> using namespace std; const int N=55,M=105; int n,m; char str[M][N]; struct Node { int id,num; }node[M]; 阅读全文
posted @ 2011-12-03 16:59 不是我干的 阅读(207) 评论(0) 推荐(0)
  2011年12月1日
摘要: 题意:给一个固定长度为L的画板有两个操作:C A B C:区间AB内涂上颜色C。P A B:查询区间AB内颜色种类数。思路:首先显然是要线段树。每个节点有如下参数:l,r 表示区间。int color表示颜色,对于颜色要用位运算。刚开始我的做法是对于每个C操作,就更新区间为AB的节点及其所有子节点。然后TLE了。其实本质原因是没有理解好线段树的精髓。线段树的精髓在于插入(或者更新)和查询都是从根节点开始!所以我们无需每次涂色都更新到叶子节点。具体的解释在代码里。#include<iostream> using namespace std; int l,t,o; const int 阅读全文
posted @ 2011-12-01 23:17 不是我干的 阅读(239) 评论(0) 推荐(0)
摘要: 题意:水晶数g,农民数目p,每个农民的造价c,起始状态金钱数m,游戏结束的秒数d。每秒每个农民可以制造g个水晶。制造农民不需要时间,任何时刻都行。思路:刚开始以为是dp。其实不然。每一秒内都有固定的p[i]、m[i]。i=0,1,2,3......d;任何时刻都可以生产农民。讨论对于第i秒内,可以生产农民数目为:x=0,1,2,3.....xmax.;(xmax=m[i-1]/c);显然是在第i秒初生产最好,这样再第i秒末就可以多出这一秒这个新农民生产的水晶。p[i]是第i秒末的人数,即上一秒的人数加上在这一秒初新造出的农民数,即p[i]=p[i-1]+x;m[i]是第i秒末的钱,m[i]=m 阅读全文
posted @ 2011-12-01 20:13 不是我干的 阅读(131) 评论(0) 推荐(0)
摘要: 题意:给一行数字,只能相邻的两个交换位置。为交换多少次之后能使得这行数字里的每个数的左右数字交换。(reverse)。注意!这行数是不是在一行里,是around the table ,即是一个环。思路:如果这个不是环的话,很显然,就是冒泡排序。1 2 3 4 5冒泡排序成5 4 3 2 1 交换次数是n*(n-1)/2。但是关键点也是蛋疼点就是这个是环:当时做的时候是写了不少数组都算看看,猜出蹊跷点。这里让我想到我一个获得过acm区域赛的金奖老乡给我说有次参加某校赛的时候,本来是没戏了,但是在最后一个小时的时候,猜了三道题的解法,都是自己设定出一些数组来猜想。没想到三道题都ac了。一下次就名次 阅读全文
posted @ 2011-12-01 17:10 不是我干的 阅读(216) 评论(0) 推荐(0)
摘要: 题意:给一个矩阵。从上到下一样,(题目里说的是从下到上,但是其实一样)代码里面就是从上到下考虑。每一行到下一行都只有三个选择,左下,下,右下。所以转移方程为:dp[i][j]=min(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1])+w[i][j];因为dp还很不熟练。刚看到题目的时候其实第一反应是类似广搜的去模拟一下差不多,反正每一格只会影响下一行的三格。然后写的时候就注意到了其实就是dp。#include<iostream> #define min(a,b) (a<b?a:b) using namespace std; const int N=1 阅读全文
posted @ 2011-12-01 16:34 不是我干的 阅读(180) 评论(0) 推荐(0)
摘要: 题意:很好懂。其实就是大小关系,如果a>b ,b>c 如果再出现个c>a即不合法。思路:floyd传递闭包。floyd的典型应用了。floyd处理之后,如果mat[a][a]=true,即可说明出现了闭环。即不合法。#include<iostream> using namespace std; const int N=105; int n,m; bool mat[N][N]; void floyd() { for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) ... 阅读全文
posted @ 2011-12-01 16:21 不是我干的 阅读(162) 评论(0) 推荐(0)