Codeforces Round #316 (Div. 2)ProblemC

Codeforces Round #316 (Div. 2)ProblemC
題目大意:有一個長度爲n的字符串,和m次詢問(1n,m300000) ,字符串由小寫字母和’.’組成,每次詢問給一個整數x和字符c(1xin,ci.) ,用c這個字符去替換原字符串x的位置的字符,然後統計連續的兩個’.’的個數。關於統計’.’的個數:例如,“h…i..”,前3個連續點,有2組連續的兩個’.’,後連續的兩個點有1組,所以答案是3。所以就是統計字符串裏連續兩個’.’的個數。

假設先已經統計連續兩個’.’的個數爲cnt。每次詢問將分幾種情況討論:

1.若st[x]字符跟c字符的類型相同,即同爲’.’或者同爲字母,不論怎麼替換總個數cnt是不會改變的
2.若st[x]是字母,c是’.’,增加了’.’的個數,則字符串中有可能會增加連續兩個’.’的個數,至於增加多少個呢?若x前一個字符st[x - 1]是個’.’,則會增加1組連續兩個’.’,同理st[x + 1]是’.’也會增加一組,其他情況則cnt不變。
3.若st[x]是’.’,c是字母,則字符串中有可能會減少連續兩個’.’的個數,同2,只是會減少而已

所以,經過以上分析,可在O(max(n,m)) 時間複雜度內求得答案。

代碼如下,僅供參考:

/*************************************************************************
    > File Name: c.cpp
    > Author: Royecode
    > Email: [email protected] 
    > Created Time: 2015年08月14日 星期五 00時20分16秒
 ************************************************************************/

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    char st[n + 7];
    scanf("%s", st + 1);
    int cnt = 0;
    for(int i = 1; i <= n; ++i)//求得連續的'.'的個數
        if(st[i] == '.' && st[i + 1] == '.') cnt++;
    while(m--)
    {
        int p;
        char ch[2];
        scanf("%d%s", &p, ch);
        if(ch[0] == '.' && st[p] >= 'a' && st[p] <= 'z')//增加
        {
            if(st[p - 1] == '.') cnt++;
            if(st[p + 1] == '.') cnt++;
        }
        else if(ch[0] >= 'a' && ch[0] <= 'z' && st[p] == '.')//減少
        {
            if(st[p - 1] == '.') cnt--;
            if(st[p + 1] == '.') cnt--;
        }
        printf("%d\n", cnt);
        st[p] = ch[0];
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章