1. 程式人生 > >K - Known Notation ZOJ - 3829[貪心]

K - Known Notation ZOJ - 3829[貪心]

題意:給出一個字串(只含有數字和乘號),以及兩種操作,分別為:

  1. 向該字串中插入一個字元(數字或者乘號)
  2. 交換字串中任意兩個字元

回答最少需要幾次操作能把字串變成一個合法的字尾表示式。


題解:我們首先考慮如果乘號放在最後肯定是沒有問題的,無論怎樣只要有足夠多的數字乘號一定能夠用完。同理數字放在最前面也是可以的。根據上述理論貪心即可,如果該字元是乘號,那麼判斷他前面的運算數字的個數(多了不影響),如果不夠的話將乘號與最後一個數字交換位置,如果沒有數字那麼就插入相應的字元。

陣列開小竟然會TLE,心裡難受 :

( :(


a c   c o d e

: ac\ code:

/****hqx is the best****/

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define met(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define per(i, a, b) for(int i = a; i >= b; i--)
const int maxn = 1e3 + 10; const int inf = 0x3f3f3f3f; int T; char s[maxn]; int main() { scanf("%d", &T); while(T--) { scanf("%s", s); int len = strlen(s), dig = 0, ch = 0; rep(i, 0, len - 1) { if(s[i] == '*') ch++; else dig++; } int num = 0, ans = 0; rep(i, 0, len - 1) { if(s[i] == '*') { if(num >= 2) { num--; } else { if(num == 1) { if(dig >= ch + 1) { for(int j = len - 1; j > i; j--) { if(s[j] == '1') { swap(s[i], s[j]); break; } } ans++; num++; } else { ans++; dig++; } } else { if(dig >= ch + 1) { ans++; num++; for(int j = len - 1; j > i; j--) { if(s[j] == '1') { swap(s[i], s[j]); break; } } } else { ans++; dig++; num = 1; if(dig >= ch + 1) { ans++; num++; for(int j = len - 1; j > i; j--) { if(s[j] == '1') { swap(s[i], s[j]); break; } } } else { dig++; ans++; } } } } } else { num++; } } //cout << s << endl; printf("%d\n", ans); } return 0; }