HDU - 6103 Kirinriki(字符串匹配+思维)

题目大意:

就是给你一个字符串,让你从中选取两个不相交的子串,使得它们在差不超过 m 的前提下尽可能的长,问你最长可能的长度。两个子串的差定义为两个子串一个正向遍历一个同时反向遍历,对应位置字符差的绝对值的和。

分析:

办法就是把所给字符串 a 倒序生成字符串 b ,然后问题就转化成了如何将 a b 字符串匹配才能得到最长的符合要求的匹配长度。那么我的想法就是把 a b 字符串错位,对于每一种错位状况,我用一种类似于尺取法的办法在 O(n) 的之间内,取出可能的最大长度。那么对于大约 2*n 种错位状况,我就能在大约 O( n2 )的时间内求得该问题的解。

代码:

#include<bits/stdc++.h>
#define maxn 5050
using namespace std;

int test=0;
char a[maxn],b[maxn];
int n,m;


int main()
{
    scanf("%d",&test);
    while(test--)
    {
        scanf("%d",&m);
        scanf("%s",a);
        n=strlen(a);
        for(int i=0;i<n;i++)
        {
            b[i]=a[n-i-1];
        }
        int ans=0;
        int best=0,val=0;
        for(int j=0;j<n-1;j++)
        {
            best=0;
            val=0;
            for(int i=0;i<(n-j)/2;i++)//iºÅºÍi+jºÅ±È
            {
                val+=abs(a[i]-b[i+j]);
                if(val>m)
                {
                    val-=abs(a[i-best]-b[i+j-best]);
                    continue;
                }
                best++;
            }
            if(ans<best)
            {
                ans=best;
            }
        }

        for(int j=0;j<n-1;j++)
        {
            best=0;
            val=0;
            for(int i=0;i<(n-j)/2;i++)//iºÅºÍi+jºÅ±È
            {
                val+=abs(b[i]-a[i+j]);
                if(val>m)
                {
                    val-=abs(b[i-best]-a[i+j-best]);
                    continue;
                }
                best++;
            }
            if(ans<best)
            {
                ans=best;
            }
        }

        printf("%d\n",ans);

    }

}

总结:

第六场多校赛了,这一场自认为发挥还是不错。本来开始之前就想吃午饭,但是突然一狠心,还是不吃了,一会要是能 ac 3题就出去吃好的!没够就晚上也不吃了。结果因为怕饿一晚上还是拼命做了3题出来,刚刚吃得还挺爽。
其实感觉这三道都是说不出什么算法,就是比较靠技巧的,主要是看ac人数大概估计了题的难度,少走了好多弯路。主要是对于这一道题,想的时候,我也想到了会不会是要用 dp ,但是这次真的是脑子没敢停(实在是想吃肉了),感觉想到解法的过程是一种类似于广搜的过程,向 dp 的方向想一点,遇到困难再换成暴力的思想,遇到困难想不到的时候,又回去继续想 dp ,然后又找不到合适状态,结果又换成别的方向,反正各个方向都想了一下,但都不是很深,因为我觉得300人 ac 的题真的不应该太复杂。也许是真的有点着急了,不过还是想到了比较简单的办法。后面发现代码能力还是低,几十行的代码,边界就能想乱。(不是原理想不明白,是 i j 从零开始从一开始,奇数偶数想不过来)好在还是ac了这道“吃饭题”。激动地直接去约饭了,也没安排好~
但是感觉最关键的一步是想到要把 a 字符串倒序生成 b 然后放到一起比(虽然部分区域无法取到),如果只是想把一个字符串分两个合适的部分,而把这个问题看成是在一串数中找两个子串的合适的边界位置的话,感觉就很难想出结果了,因为这样很难有效利用字符串长度相同这个条件。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值