BestCoder#27 2015/1/24 前面的基本思路来自hdu的官网解答 1001 Jump and Jump... 首先算出每个人的成绩,然后sort一下就好了,考虑n的范围只有2或者3,只要用if+swap也是可行的。 1002 Taking Bus 题目大意: 给你一个线路上的站点个数和站点之间的距离,根据发车的个数确定发车站点,再根据上车人的站点和目的地计算出时间,车从左往右然后折返着开,一个单位距离用一秒 输入输出样例:简单的分类讨论,设s,x,y分别表示公交的始发站,起点和终点。大概有这样几种情况:1. s≤x<y, 2. x<s<y,3. x<y≤s, 4. s≤y<x, 5. y<s<x, 6. y<x≤s分别写出公式即可。答案应该会超过int,注意要用long long。输入样例1 (T-组数) 7 3(7为n,表示站点数;3为m,乘车人数) 2 3 4 3 4 5 (七个站之间的距离) 1 7(第一个人,从站1到站7,出发站为1) 4 5(第二个人,从站1到站7,出发站为2) 5 4(始发站是这么算的:第i个人的话,始发站为(i-1)mod n +1)输出样例21 10 28 提示: 对于第一个人, 公交在站点1出发, 然后这个人在时刻0上车。21秒之后,公交到达站点7。 对于第二个人,公交在站点2出发。7秒之后,公交到达站点4,这个人上车。之后又过了3秒,公交到达站点5.总共用了10秒。 对于第三个人,公交在站点3出发。7秒之后,公交到达站点5,这个人上车。之后过了9秒,公交达到站点7,然后转向开往站点0。之后经过12秒,公交达到站点4。因此总共需要28秒时间。
解题思路:
首先是分情况讨论,其次呢,关于怎么计算一段路程的长度,这个呢,我们很容易联想到线段树的干活,其实除了线段树,还有一个简单方法,就是开一个distance[]数组,distance[i]=前i个点的距离,那么i-j的距离不就是distance[j]-distance[i]吗
经验总结:
注意取值的大小,我就是因为一开始没有注意long long的问题所以wrong answer了!#include #include #include #include #define maxn 100003 using namespace std; long long int vals ; long long int val[maxn] ; struct line { int left,right ; long long int sum ; }a[maxn*4]; void buil ( int l , int r , int n ) { int mid ; a[n].left = l ; a[n].right = r ; if( l == r-1 ) { a[n].sum = val[l] ; return ; } mid = ( l + r ) / 2 ; buil( l , mid , 2*n ) ; buil( mid , r , 2*n+1 ) ; a[n].sum = a[2*n].sum + a[2*n+1].sum ; } long long int getval ( int i , int j ,int start ) { int mid ;long long int sum = 0 ; if( i == j ){ return 0; } if( a[start].left == i && a[start].right== j ){ return a[start].sum ; } mid = ( a[start].left + a[start].right )/2 ; if( mid >= j ){ sum += getval( i , j , 2*start ) ; } else{ if( mid <= i ){ sum += getval( i , j , 2*start+1 ) ; } else{ sum += getval( i , mid , 2*start ) ; sum += getval( mid , j , 2*start+1 ) ; } } return sum ; } int main() { int T,n,m; int s1,s2,ss; int ju1,ju2; scanf("%d",&T); while(T--){ scanf("%d %d",&n,&m); for(int i = 1 ; i1003 Matching on Array题目大意: 给你一个Alice串,很长的整数串,给你一堆Bob串,很多个整数串,问Alice串里有几个Bob串出现,这里出现定义为存在一个Alice的连续子串,其前后比例与Bob串相同,比如2 4 6 8 的Alice串,1 2 4 的Bob串,那么2 4 6 就与1 2 4 匹配 输入输出样例:输入样例2(组数T) 4 1(Alice串长,Bob串个数) 2 4 8 16(alice 串) 2 1 2(Bob串长 Bob串) 5 3 2 4 2 4 6 3 1 2 1 1 5 2 16 8输出样例3(2 4 4 8 8 16 共3个) 7
首先我们考虑m=1的情况。给定两个数组A={a1,a2,…,an}和B={b1,b2,…,bk},问B在A中出现了几次。令ci=ai+1ai,1≤i<n,同样令di=bi+1bi,1≤i<k,那么上述问题可以转化为ci和di的模式匹配问题,这个正确性显然,也没有什么好证明的。于是对于m=1的情况只有用个kmp即可搞定。现在考虑m>1的情况,我们考虑用ac自动机来做。考虑到字符集并不是普通的数字,而是一个分数,我们不放搞个分数类,然后用map存转移边。用m个模式串(Bob的序列)建好自动机之后,把文本串(Alice的序列)在自动机上跑一遍即可统计出答案。解题思路:首先,我们得有个问题转化,不是求一个子串C,满足 C与Bob子串成比例吗,那么我们就有:c2/b2 = c1/b1;这其实就转成:c2/c1 = b2/b1; c3/c2 = b3/b2 那么Bob子串就可以转化成比例串了
最后其实就是一个ac自动机变形题,不过这个变形还挺巧妙的,我们把储存的字符串变成比例,而这样的改变也会使得我们固定的26的空间大小发生改变,为此,我们利用map来解决
1. 利用map的关键字,我们可以不固定每个比例值的分支个数和数值
2. 关键字的选取:比如比例为 b1 b2 那么 b2/b1的值就记为b2/gcd(b1,b2)*100001+b1,可以证明,这个关键字独一无二经验总结:此题很棒啊,不过由于是ac自动机的变形,所以很多东西都要转化过来,比如map数组mp,mp[i]相当于第i个节点,map[i][j]相当于第i个节点比例为j的那个子节点,其值为子节点的序号 【本代码,来自http://blog.csdn.net/u013368721/article/details/43118531的分享】#include #include
BestCoder#27
最新推荐文章于 2020-09-23 12:02:18 发布
本文精选了几道算法竞赛题目并提供了详细的解题思路与代码实现,包括基于成绩排序的简单问题、公交车路线时间计算问题以及比例匹配问题。通过具体实例展示了如何使用线段树和AC自动机等高级数据结构来解决复杂问题。

495

被折叠的 条评论
为什么被折叠?



