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;
}