题目大意:
给定一个只含 1-9 的数字和 ‘*’ 的字符串,让你只用如下两个操作使得这个字符串成为逆波兰式:
1) 增加:在任意位置增加一个数字
2) 交换:可以交换字符串中任意两个字符题解:
要满足条件,最少的情况下数字个数numd>=星号个数nums+1,如果不满足,就只能靠添加了,要添加nums+1-numd个
之后采用贪心的策略。从左往右扫描一遍字符串,动态更新numd和nums,如果发现numd<nums+1,先使用添加,如果添加用完,则和后面的数字交换。
训练赛的时候遇到的这道题,只可惜当时没有肝出来。想到可能是dp,可能是字符串的一些算法,却不敢想是贪心。。。。
#include<bits/stdc++.h>
#include<cmath>
using namespace std;
int main()
{
int T;
cin>>T;
string s;
while(T--)
{
cin>>s;
int len=s.length();
int nums=0,numd=0;
for(int i=0; i<len; ++i)
if(s[i]=='*')
nums++;
numd=len-nums;
if(nums==0)
{
cout<<0<<endl;
continue;
}
//数字个数要>=星号个数+1
int need=0;
if(numd>=nums+1)
need=0;
else need=nums+1-numd;
int digit=0,sign=0;
int ans=need;
//这里是在算交换的次数
for(int i=0; i<len; ++i)
{
if(s[i]!='*')
++digit;
else
{
++sign;
if(digit<sign+1)
{
if(need>0)
{
--need;
++digit;
}
else
{
//数字不够了要把当前一个数字和后面的一个符号交换
++digit;
--sign;
++ans;
}
}
}
}
cout<<ans<<endl;
}
return 0;
}