Known Notation
题意:添加字符或者交换字符使得构成合法的后缀表达式,求最少的操作次数。
思路的中心思想:
数字尽量在前,星号尽量在后。
插入操作:
当数字不够,只需在字符串的前面插入数字即可
//假设我们需要插入号,必然因为前面的操作数过多,但是由于合并字符为数字的随意性,添加无非错误
交换操作:
当不满足条件时,交换操作字符和最后的数字。
对于字符串的遍历:
当遍历到某个位置时,如果统计得到的字符个数-数字个数>=1
时,交换字符。
当最后以为不是*时添加操作字符。
[代码如下]
- /*************************************************************************
- > File Name: zoj3829.cpp
- > Author: cy
- > Mail: 1002@qq.com
- > Created Time: 14/10/13 18:48:56
- ************************************************************************/
- #include<iostream>
- #include<cstring>
- #include <algorithm>
- #include<cstdlib>
- #include<vector>
- #include<cmath>
- #include<stdlib.h>
- #include<iomanip>
- #include<list>
- #include<deque>
- #include<map>
- #include <stdio.h>
- #include <queue>
- #define maxn 50000+5
- #define inf 0x3f3f3f3f
- #define INF 0x3FFFFFFFFFFFFFFFLL
- #define rep(i,n) for(i=0;i<n;i++)
- #define reP(i,n) for(i=1;i<=n;i++)
- #define ull unsigned long long
- #define ll long long
- #define cle(a) memset(a,0,sizeof(a))
- using namespace std;
- string s;
- int ans;//统计操作次数
- int numop;//*号个数
- int numn;//数字个数
- int len;
- void init()
- {
- numop=0,ans=0,numn=0;
- int i;
- len=s.size();
- for(i=0;i<len;i++){
- if(s[i]>='0'&&s[i]<='9')numn++;
- else numop++;
- }
- }
- void doit()
- {
- if(numn==len){
- printf("0\n");
- return;
- }
- if(numop>=numn){
- ans=numop-numn+1;
- numn=numop-numn+1;
- numop=0;
- }
- else{
- numop=0;numn=0;
- }
- int ip=len-1;
- int i;
- rep(i,len){
- if(s[i]=='*')numop++;else numn++;
- if(numop>=numn){
- while(true){
- if(s[ip]>='0'&&s[ip]<='9'){
- break;
- }
- else ip--;
- }
- swap(s[ip],s[i]);
- numn++;
- numop--;
- ans++;
- }
- }
- if(s[len-1]!='*')ans++;
- printf("%d\n",ans);
- }
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("in.txt","r",stdin);
- //freopen("out.txt","w",stdout);
- #endif
- int T;
- cin>>T;
- while(T--)
- {
- cin>>s;
- init();
- doit();
- }
- return 0;
- }