zoukankan      html  css  js  c++  java
  • HDU 6103 Kirinriki 枚举长度 尺取法

      题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6103

      题目描述: 定义两个相同长度的字符串的值为首尾开始字符串的ASCII相减, 求一个字符串中任取两个相同长度的不重叠的值不超过m的最大长度

      解题思路: 求连续区间不超过某一个上限或者不低于某个下限的应该用尺取法 ,复杂度为O(n),  本题n是5000所以O(n^2)可行, 枚举前缀和后缀(通过枚举前缀, 再将字符串翻转枚举前缀进行), 再进行尺取 

      代码:  代码中有注释

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <map>
    #include <cstring>
    #include <iterator>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <deque>
    
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    using namespace std;
    
    const int maxn = 21000;
    char str[maxn];
    int m,len;
    
    int solve() {
        int ans = 0;
    //    cout << len << endl;
        for( int i = len; i >= 1; i-- ) { // 枚举每一个前缀
    //        cout << "--- " << endl;
            int cnt = i/2-1;
            int  d = 0,t = 0,p = 0;
            for( int j = 0 ; j <= cnt; j++ ) {
                d += abs( str[1+j]-str[i-j] ); // 加上权值
                if( d > m ) {
                    d -= abs( str[1+p]-str[i-p] ); // 将最前面的剪掉, 将最后面剪掉, 这样下一次循环还会加的是最后面
                    d -= abs( str[1+j]-str[i-j] );
                    p++; // 记录第一个字符串最前面的指针
                    t--; // 记录单个字符串的长度
                    j--; // 记录第一个字符串最后面的指针
                }
                else {
                    t++; // d <= m 就是说还可以向后再加一个字符串长度可以加一
                    ans=max(ans,t);
                }
            }
        }
        return ans;
    }
    
    int main() {
        int T;
        scanf( "%d", &T );
        while( T-- ){
            int ans = 0;
            scanf( "%d%s", &m, str+1 );
            len = (int)strlen(str+1);
            ans = max( ans, solve() );
            reverse( str+1, str+len+1 ); // 后缀和
            ans = max( ans, solve() );
    //        reverse( str+1, str+len+1 );
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

      思考: 以前看过尺取法, 忘了......以后记住求连续区间不超过某一个上限或者不低于某个下限的长度应该用尺取法 

  • 相关阅读:
    根据对象的属性排序数组
    将多维数组的元素全部取出,组成一维数组的方法
    微信公众号报错 config:invalid signature
    改造业务代码
    微信公众号调用扫一扫
    JQuery :contains选择器,可做搜索功能,搜索包含关键字的dom
    【转】超全功能测试方法集锦——(通用黑盒功能:测试新人必收攻略)
    Oracle 查看表空间的大小及使用情况sql语句
    oracle数据库 参数open_cursors和session_cached_cursor详解!
    使用MITab操作MapInfo地图文件
  • 原文地址:https://www.cnblogs.com/FriskyPuppy/p/7344246.html
Copyright © 2011-2022 走看看