1. 程式人生 > >【枚舉】【尺取法】hdu6103 Kirinriki

【枚舉】【尺取法】hdu6103 Kirinriki

兩個 n) can sin 相等 amp true har 字符串

兩個等長字符串A,B的距離被定義為技術分享

給你一個字符串,問你對於所有長度相等的不相交子串對,其距離不超過m的前提下,最長的長度是多少。

枚舉對稱軸,兩側先貪心地擴展到最長,超過m之後,再縮短靠近對稱軸的端點,如此反復進行,每次更新答案的時候,都用的是當前“近對稱軸端點”固定時的最長值。

復雜度O(n^2)。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int Abs(int x){
	return x<0 ? (-x) : x;
}
int T,m,n;
char a[5005];
int main(){
	scanf("%d",&T);
	for(;T;--T){
		int ans=0;
		scanf("%d%s",&m,a+1);
		n=strlen(a+1);
		for(int i=1;i<n;++i){
			if(i==6){
				i=6;
			}
			int sum=0;
			int p1=i,p2=i+1,q1=i,q2=i+1;
			while(p1>=1 && p2<=n){
				while(sum<=m && p1>=1 && p2<=n){
					sum+=Abs(a[p1]-a[p2]);
					if(sum<=m){
						ans=max(ans,q1-p1+1);
					}
					--p1;
					++p2;
				}
				while(sum>m){
					sum-=Abs(a[q1]-a[q2]);
					--q1;
					++q2;
					if(sum<=m){
						ans=max(ans,q1-p1);
					}
				}
			}
		}
		for(int i=2;i<n;++i){
			int sum=0;
			int p1=i-1,p2=i+1,q1=i-1,q2=i+1;
			while(p1>=1 && p2<=n){
				while(sum<=m && p1>=1 && p2<=n){
					sum+=Abs(a[p1]-a[p2]);
					if(sum<=m){
						ans=max(ans,q1-p1+1);
					}
					--p1;
					++p2;
				}
				while(sum>m){
					sum-=Abs(a[q1]-a[q2]);
					--q1;
					++q2;
					if(sum<=m){
						ans=max(ans,q1-p1);
					}
				}
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

【枚舉】【尺取法】hdu6103 Kirinriki