ZOJ - 3829 Known Notation(模拟+贪心)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3829
给定一个字符串(只包含数字和星号)可以在字符串的任意位置添加一个数字,还可以交换任意两个字符,问需要多少步能得到一个合法后缀表达式.
如果数字<星号+1 那么必须要添加数字,那么肯定是添加在字符串前面是最优的,然后从头到尾扫描整个串,如果遇到星号并且前面出现的数字>=2
数字减1,否则就要从后往前找第一个非*的数字然后与星号交换.
注意全为数字的情况,和处理完后字符串末尾不为*就要加上*号.
1 #include <cstdio> 2 #include <string> 3 #include <iostream> 4 using namespace std; 5 int main() 6 { 7 //freopen("a.txt","r",stdin); 8 int t,n; 9 string s; 10 scanf("%d",&t); 11 while(t--) 12 { 13 cin>>s; 14 n=s.length(); 15 int num1=0,num2=0; 16 for(int i=0;i<n;i++) 17 { 18 if(s[i]=='*') num1++; 19 else num2++; 20 } 21 //cout<<num1<<num2<<endl; 22 if(num2==n) {printf("0\n");continue;} 23 int ans=0; 24 if(num2<=num1) 25 { 26 ans=num1+1-num2; 27 for(int i=0;i<ans;i++) 28 s="1"+s; 29 } 30 num1=0; 31 n=s.length(); 32 for(int i=0;i<n;i++) 33 { 34 if(s[i]=='*') 35 { 36 if(num1>=2) num1--; 37 else 38 { 39 for(int j=n-1;j>=0;j--) 40 { 41 if(s[j]!='*') 42 { 43 s[i]='1';s[j]='*'; 44 break; 45 } 46 } 47 ans++; 48 num1++; 49 } 50 } 51 else num1++; 52 } 53 if(s[n-1]!='*') 54 { 55 // cout<<s[n-1]<<endl; 56 ans++; 57 } 58 printf("%d\n",ans); 59 } 60 return 0; 61 }