Codeforces Round #750 (Div. 2) C 双指针 模拟

题目

给你一串字符串,你选择一种字符来删除使他变成回文字符串,选择了就只能删除字符串里的任意个数的这种字符。
求最少删除的次数。

题解思路

一开始没看清题目,以为任意都能删除。
后来发现只能选择一种,那样就很显然了。
直接找到第一个不同的字符对,删除他们两个其中一个。如果能得到回文串就取最小值。
之前相同的肯定不用删,因为加和不加他们对里面的回文串是没有影响的,删除他们反而得不到最优解。
考虑删除某个字符时,我们用双指针来跑,不同而且可以被删除就删,不能就得不到回文串。

可惜我模拟错了。真菜啊。

AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;

const  int  INF =  0x3f3f3f3f;

char s[200100] ;

int main ()
{
    ios::sync_with_stdio(false);cin.tie(0);
    int T ;
    cin >> T ;
    while ( T -- )
    {
        int n ;
        cin >> n ;
        cin >> s ;
      //  cout << s << "\n" ;
        int ans = n+1 , book = 0 ;
        int p1 = 0 , p2 = n- 1  ;
        while ( p1 < p2 )
        {
            if ( s[p1] != s[p2] )
            {
                book = 1 ;
                char k1 = s[p1] ;
                char k2 = s[p2] ;
                int tmp = 0  ;
                int t1 = p1 , t2 = p2 ;
                while ( t1 < t2 )
                {
                    if ( s[t1] == s[t2] )
                    {
                        t1++;
                        t2--;
                    }else if ( s[t1] == k1 )
                    {
                        t1++;
                        tmp++;
                    }else if ( s[t2] == k1 )
                    {
                        t2--;
                        tmp++;
                    }else
                    {
                        tmp  = - 1 ;
                        break ;
                    }
                }
                if ( tmp != -1 )
                {
                    ans = min( ans , tmp ) ;
                }


                tmp = 0  ;
                t1 = p1 , t2 = p2 ;
                while ( t1 < t2 )
                {
                    if ( s[t1] == s[t2] )
                    {
                        t1++;
                        t2--;
                    }else if ( s[t1] == k2 )
                    {
                        t1++;
                        tmp++;
                    }else if ( s[t2] == k2 )
                    {
                        t2--;
                        tmp++;
                    }else
                    {
                        tmp  = - 1 ;
                        break ;
                    }
                }
                if ( tmp != -1 )
                {
                    ans = min( ans , tmp ) ;
                }
                break ;
            }else
            {
                p1++ ;
                p2-- ;
            }
        }
        if (!book)
            cout << "0\n" ;
        else if ( ans != n+1  )
            cout << ans << "\n" ;
        else
            cout << "-1\n" ;
    }

    return 0 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值