该题表面让我们求一个字符串的问题,但是却可以转化成求斜率的问题, 紫书上已经说的很清楚了,我这里就不再赘述 。
代码如下 :
#include<bits/stdc++.h> using namespace std; const int maxn = 100000 + 5; int n,T,L; double a[maxn],p[maxn]; char s[maxn]; int campare(int x1,int x2,int x3,int x4){ //直线p[x1]p[x2]的斜率减去p[x3]p[x4]的斜率 return (a[x1] - a[x2-1])*(x3-x4+1) - (a[x3] - a[x4-1])*(x1-x2+1); } int main(){ scanf("%d",&T); while(T--){ scanf("%d%d%s",&n,&L,s); int len = strlen(s); a[0] = 0; for(int i=0;i<len;i++){ a[i+1] = a[i] + s[i] - '0'; //a[i]为前i项的和 } int l = 1, r = L , i = 0 , j = 0; //用两个指针 i 和 j 来动态维护下凸区间。 for(int t = L;t <= len;t ++) { while(j - i > 1 && campare(t-L,p[j-2],t-L,p[j-1])>=0) j--; //删除上凸的点 p[j++] = t - L + 1; //增加新元素 while(j - i > 1 && campare(t,p[i+1],t,p[i])>=0) i++; //确定新的切点,因为切点的x坐标一定是不断增加的 int c = campare(r,l,t,p[i]); if(c < 0 || c == 0 && (r-l)>(t-p[i])) { l = p[i] ; r = t ; } } cout<<l<<' '<<r<<endl; } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/weizhuwyzc000/article/details/46777845