Stones【中石油个人赛第十七场I】

Stones

题目链接(传送门) 来源:upc12899

题目描述

There are N stones arranged in a row. Every stone is painted white or black. A string S represents the color of the stones. The i-th stone from the left is white if the i-th character of S is ., and the stone is black if the character is #.

Takahashi wants to change the colors of some stones to black or white so that there will be no white stone immediately to the right of a black stone. Find the minimum number of stones that needs to be recolored.

Constraints
1≤N≤2×105
S is a string of length 
N consisting of . and #.

输入

Input is given from Standard Input in the following format:

N
S

输出

Print the minimum number of stones that needs to be recolored.

样例输入

3
#.#

样例输出

1

提示

It is enough to change the color of the first stone to white.

题目描述:

    输入字符串只包含 ‘ . ’ 和 ‘ # ’,可以改变任意数目使 ‘ . ’ 变为 ‘ # ’ 或使‘ # ’ 变为 ‘ . ’,最终要求 ‘ # ’的右边不可以紧挨着 ‘ . ’,输出最小变化数目。

思路:

    比赛的时候想的是每次碰到 ‘#.’ 就判断 ‘ # ’(cnt1)和‘ . ’(cnt2)的个数,令cnt+=min(cnt1,cnt2)但一直错,也找不出错误的样例,后来同学给了组样例:

                                ##.#...# #       我的计算结果是 2  明显不对

    同学让我考虑末状态(最终状态):

       1、......

       2、####

       3、.....#### (‘ . ’全部出现在‘ # ’的左边)

   也只有上面几种情况

   于是:

       对于1、2很好判断,直接前缀和就能求出

       对于3 枚举....####交叉的位置(这个样例交叉位置是3和4)

   整体取最小值就能解决啦

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int MAX=2e5;
struct node{
    int cnt1;
    int cnt2;
}num[MAX+5];
int sum[MAX+5];
char a[MAX+5]; 
int main()
{
    int la;
    scanf("%d%s",&la,a);
    int cnt1=0,cnt2=0;
    for(int i=0;i<la;i++){
        if(a[i]=='#') cnt1++;
        else cnt2++;
        num[i].cnt1=cnt1;
        num[i].cnt2=cnt2;
    }
    int cnt=0;
    for(int i=0;i<la;i++){
        sum[cnt++]=(num[i].cnt1+(num[la-1].cnt2-num[i+1].cnt2));
    }
    sum[cnt++]=num[la-1].cnt2;
    sum[cnt++]=num[la-1].cnt1;
    sort(sum,sum+cnt);
    printf("%d\n",sum[0]);
    return 0;
}

 

posted @ 2019-07-29 09:42  XJHui  阅读(100)  评论(0编辑  收藏  举报