中南 1294 coins 重点是想法,外加STL中的map

题目网址:http://122.207.68.93/OnlineJudge/problem.php?id=1294

题意是给你一个字符串,字符串中只包含O和R,要你求满足条件的最长的连续子序列的长度,输出该长度。。条件是,连续子序列中O的个数是R的个数的K倍(K已知)

想法如下:

设这个满足条件的子序列O的个数为x,R的个数为y

则有x = k*y

即有x + (-k)*y = 0

那么如果令R的权值为-k,O的权值为1,这段序列的和即为0

令sum[i]为前i项之和。。。如果有sum[i] == sum[j],证明a(i+1) + a(i+2) + ```` + a(j)的和为0,也就是说出现可行解,其长度为j-i...

线性扫一遍,查找是否出现重复值就用map,降低时间复杂度

所以大概的复杂度就是O(n*logn)...

贴代码:

 1 #include <cstdio>
 2 #include <map>
 3 #include <cstring>
 4 #define LL long long int
 5 using namespace std;
 6 int main()
 7 {
 8 //    freopen("in.cpp","r",stdin);
 9     int len,k;
10     scanf("%d%d",&len,&k);//长度和K值
11     char a;
12     int max = 0;//用来记录最后的结果,初始状态为0
13     map<LL,int> m;
14     LL sum = 0;
15     m[0] = 0;
16     getchar();
17     for(int i=1; i<=len; ++i)
18     {
19         a = getchar();
20         if(a == 'O')
21             ++sum;//O,加1
22         else sum -= k;//R,加-K
23         map<LL,int>::iterator it;
24         it = m.find(sum);
25         if(it != m.end())//出现重复
26         {
27             if(max < i-(*it).second)//出现更大长度
28                 max = i-(*it).second;//更新MAX
29         }
30         else
31             m[sum] = i;//未出现重复,保存
32     }
33     printf("%d\n",max);
34     return 0;
35 }
View Code

 

posted on 2013-05-21 20:27  allh123  阅读(146)  评论(0编辑  收藏  举报

导航