1. 程式人生 > >Codeforces Round #316 (Div. 2) C. Replacement

Codeforces Round #316 (Div. 2) C. Replacement

ont 復雜 problem tar ret ng- include return 題目

題意:給定一個字符串,裏面有各種小寫字母和’ . ‘ ,無論是什麽字母,都是一樣的,假設遇到‘ . . ‘ ,就要合並成一個‘ .‘,有m個詢問,每次都在字符串某個位置上將原來的字符改成題目給的字符,問每次須要多少次合並次數。才使字符串沒有‘ .. ‘


思路:最原始的想法,就是對於每一次詢問,都遍歷整個字符串。這樣時間復雜度o(n*m),就高達10^10方,非常明顯會tle。

換下思路,事實上每次詢問所改變的字符都會保留到下一次。也就是下一次的次數就會受到上一次的影響,那麽我僅僅要就算出第一次的合並次數,以下的都能夠推出來


題目鏈接:http://codeforces.com/problemset/problem/570/C



#include<bits/stdc++.h>
using namespace std;
int n,m,cnt;
char a[300005],b[10];
int main(void)
{
    scanf("%d%d",&n,&m);
    scanf("%s",a+1);
    scanf("%d%s",&cnt,b);
    a[cnt]=b[0];//處理第一次
    int ret,ans=0,flag;
    for(int i=1; i<=n; i++)
    {
        ret=0;
        flag=0;
        while(a[i]=='.')//假設一個子序列全都是'.',假設有ret個'.',那麽合並次數就是ret-1;
        {
            i++;
            ret++;
            flag=1;
        }
        if(flag) ans+=ret-1;
    }
    printf("%d\n",ans);
    for(int i=1; i<m; i++)//處理剩余的m-1次,每一次的ans均由上一次推出
    {

        scanf("%d%s",&cnt,b);
        char ch=a[cnt];
        a[cnt]=b[0];
        if(b[0]=='.'&&ch!='.')//假設這一次由字母變成'.',檢查前後是否有'.',有一個的話合並次數就要+1
        {
            if(a[cnt-1]=='.') ans++;
            if(a[cnt+1]=='.')  ans++;
        }
        else if(b[0]!='.'&&ch=='.')//由字母變成'.'
        {
            if(a[cnt-1]=='.') ans--;
            if(a[cnt+1]=='.')  ans--;
        }
        printf("%d\n",ans);
    }
    return 0;
}


Codeforces Round #316 (Div. 2) C. Replacement