题意,哎!说道题意就蛋疼啊,比赛的时候就愣是把这个题目读成数字可以随意组合,比如123 可以拆成1 23 ,12 3 ,1 2 3,结果显然,水题当神题,各种想不出来,然后就显然的悲剧了,现在说下这个题目的意思给你一个串问你最少多少步操作可以把这个串变成合格的表达式组,每个合格表达式都是AB*的形式,A,B是数字,而且是1位的数字,只能是1位<哎!比赛的时候sb了>,然后AB*可以变成一个数字,也是1位的,是谁不重要,操作有两种,一个是在任意位置上添加一个字母1-9或者是*,另一个就是可以任意交换两个字符,问你变成合格的组合的最少步数,好像没说明白题意啊,那么我在举几个例子。1*1:我们可以直接把中间的*和后面的1交换,变成11*,11*可以转换成数字了,答案是1步11*234**:我们先把11*变成数字假如是A。34*变成B,那么就是A2B* 然后2B*可以转换成一个数字了C,加上前面的A还是一个可发数字AC,所以是0步。*:要在前面加两个数字变成AB*才能转换成一个纯数字串 所以是2
思路:
首先我们要知道,假如最终的*个数为x,最终的数字个数a肯定是 a >= x + 1,这样的话我们的策略可以这样,我们先看看数字个数够不够,如果不够,那么先把数字填够,<这里当然是填到等于x+1的个数了,能剩则剩>,还有就是要知道,根本不用填*因为填*就是在为自己增加负担,填问数字我们就可以线性扫了,从前往后,对于每一个*如果前面的数字个数不满足了,那么就把当前的*和最后面的一个数字交换就行了,这样有点贪心的意思,具体看代码吧。
#include<stdio.h>
#include<string.h>
#include<queue>
int num[1100];
char str[1100];
int main ()
{
int t ,i ,Ans;
scanf("%d" ,&t);
while(t--)
{
scanf("%s" ,str);
int l = strlen(str);
int s1 = 0 ,s2 = 0;
for(i = 0 ;i < l ;i ++)
{
if(str[i] == '*') num[i+1] = 1 ,s1 ++;
else num[i+1] = 0 ,s2 ++;
}
int now = 0;
if(s2 < s1 - 1) now = s1 + 1 - s2;
Ans = now;
for(i = 1 ;i <= l ;i ++)
{
if(num[i])
{
if(now >= 2) now --;
else
{
Ans ++;
for(int j = l ;j > i ;j --)
if(!num[j])
{
int t = num[i];
num[i] = num[j];
num[j] = t;
now ++;
break;
}
}
}
else now ++;
}
if(!num[l]) Ans ++;
if(!s1) Ans = 0;
if(num[1] && l == 1) Ans = 2;
printf("%d
" ,Ans);
}
return 0;
}