HDU 6103 Kirinriki(尺取)
2017-09-09 14:28
405 查看
Description
定义两个长度均为n的字符串A和B的距离为disA,B=∑i=0n−1|Ai−Bn−1−i|,给出一个字符串S,问S的满足距离小于m的两个等长不相交子串的长度最大值
Input
第一行一整数T表示用例组数,每组用例首先输入一整数m表示对S的子串距离的限制,之后输入一个只有小写字母的字符串S(T≤100,0≤m≤5000,2≤|S|≤5000,∑|S|≤20000)
Output
输出S的满足距离小于m的两个等长不相交子串的长度最大值
Sample Input
1
5
abcdefedcb
Sample Output
5
Solution
设两个子串分别是S[x,x+len]和S[y,y+len],其中y>x+len ,那么这两个字符串的距离为∑i+j=x+y+len|Si−Sj|,枚举i+j的和k,得到序列|Si−Sj|,i+j=k,问题变成求这个序列中满足和不超过m的最长子段,尺取法即可,总时间复杂度O(n2)
Code
定义两个长度均为n的字符串A和B的距离为disA,B=∑i=0n−1|Ai−Bn−1−i|,给出一个字符串S,问S的满足距离小于m的两个等长不相交子串的长度最大值
Input
第一行一整数T表示用例组数,每组用例首先输入一整数m表示对S的子串距离的限制,之后输入一个只有小写字母的字符串S(T≤100,0≤m≤5000,2≤|S|≤5000,∑|S|≤20000)
Output
输出S的满足距离小于m的两个等长不相交子串的长度最大值
Sample Input
1
5
abcdefedcb
Sample Output
5
Solution
设两个子串分别是S[x,x+len]和S[y,y+len],其中y>x+len ,那么这两个字符串的距离为∑i+j=x+y+len|Si−Sj|,枚举i+j的和k,得到序列|Si−Sj|,i+j=k,问题变成求这个序列中满足和不超过m的最长子段,尺取法即可,总时间复杂度O(n2)
Code
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; namespace fastIO { #define BUF_SIZE 100000 //fread -> read bool IOerror=0; inline char nc() { static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE; if(p1==pend) { p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin); if(pend==p1) { IOerror=1; return -1; } } return *p1++; } inline bool blank(char ch) { return ch==' '||ch=='\n'||ch=='\r'||ch=='\t'; } inline void read(int &x) { char ch; while(blank(ch=nc())); if(IOerror)return; for(x=ch-'0';(ch=nc())>='0'&&ch<='9';x=x*10+ch-'0'); } inline void readc(char &x) { char ch; while(blank(ch=nc())); if(IOerror)return; x=ch; } inline void reads(char *x) { char ch; while(blank(ch=nc())); if(IOerror)return; int n=0; while(1) { x[n++]=ch; if(blank(ch=nc()))break; } x ='\0'; } #undef BUF_SIZE }; using namespace fastIO; const int maxn=5005; int T,m,a[maxn]; char s[maxn]; int deal(int *a,int n) { int l=0,r=0,sum=0,ans=0; while(l<n) { while(r<n&&sum+a[r]<=m)sum+=a[r++]; ans=max(ans,r-l); sum-=a[l++]; } return ans; } int main() { read(T); //scanf("%d",&T); while(T--) { //scanf("%d",&m); //scanf("%s",s+1); read(m);reads(s+1); int n=strlen(s+1),ans=0; for(int i=2;i<=2*n;i++) { int res=0; for(int j=1;j<=(i-1)/2;j++) { int k=i-j; if(k<=n)a[res++]=abs(s[j]-s[k]); } ans=max(ans,deal(a,res)); } printf("%d\n",ans); } return 0; }
相关文章推荐
- HDU 6103 Kirinriki(尺取)
- HDU-6103 Kirinriki - 2017 Multi-University Training Contest - Team 6(尺取)
- hdu 6103(Kirinriki)
- hdu 6103 Kirinriki 尺取
- hdu 6103 Kirinriki(多校联赛)
- hdu 6103 Kirinriki 尺取
- hdu 6103 Kirinriki(尺取法)
- hdu 6103 Kirinriki 尺取
- HDU 6103 Kirinriki【尺取法】【思维题】【好题】
- hdu 6103 Kirinriki(尺取法)
- hdu 6103 Kirinriki 尺取
- HDU 6103 Kirinriki (思维 双指针)
- HDU 6103 Kirinriki
- hdu 6103 Kirinriki 尺取
- 2017多校六 1008题 hdu 6103 Kirinriki 尺取法
- HDU 6103 Kirinriki(尺取法)
- HDU 6103 Kirinriki
- hdu 6103 Kirinriki 尺取
- HDU 6103 Kirinriki
- Kirinriki HDU - 6103