CF718A Efim and Strange Grade(貪心)題解
阿新 • • 發佈:2020-11-19
演算法
貪心+無數有趣的細節
高能預警:本題細節較多,請仔細食用。
思路
從小數點往後搜,直到遇見第一個\(\geq 5\)的數字,它就是我們要四捨五入的第一個。然後從它開始往回搜,只要\(\geq 5\)就四捨五入。
正確性
小數點後位數靠前的數字越大,值越大,所以我們將第一個能“\(5\)入”的點“入”掉(因為這樣才能使得“入”過去的\(1\)價值最大)。
那為什麼往回搜的時候能入則入呢?
- 因為往回搜的數必然是小於\(5\)的,只有當前的數往前進了位才有可能\(\geq 5\),所以我們只能給當前數進位(如果它可以)。
細節
- 整數位上不能四捨五入(但可以進位)!
- 小數位與整數位的進位要分開處理!
- 可能出現一個也不能進的情況!
- 整數的最高位有可能進\(1\)! (如:\(99.459\))
- 記得判斷沒有小數點的情況!
大概就這麼多了……
參考程式碼
/* * @Author: When_C * @Date: 2020-11-19 19:29:11 * @Last Modified by: When_C * @Last Modified time: 2020-11-19 19:49:45 */ #include <cstdio> #include <cstring> using namespace std; const int maxn = 2e5 + 10; int n,t,a[maxn],top; char c[maxn]; int main(){ scanf("%d%d%s", &n, &t, c + 1); int loc,pos = -1; for(int i = 1; i <= n; ++ i){ if(c[i] >= '0' && c[i] <= '9') a[++top] = c[i] - '0'; else loc = top + 1; } for(int i = loc; i <= top; ++ i) if(a[i] >= 5){pos = i; break;} if(pos > 0){ int pre = 1; pos -= 1; t -= 1; for(int i = pos; i >= 1; -- i){ if(!pre && (!t || i < loc)) break; a[i] += pre; pre = 0; if(a[i] > 10) pre = 1, a[i] %= 10; if(a[i] == 10){ pre = 1; a[i] %= 10; if(i >= loc) pos -= 1; } if(a[i] >= 5 && t && i >= loc) pre += 1, pos -= 1, t--; } if(pre) a[0] = 1; } if(a[0]) printf("%d", a[0]); for(int i = 1; i <= pos; ++ i){ printf("%d", a[i]); if(i == loc - 1 && i != pos) printf("."); } if(pos < 0) printf("%s", c + 1); return 0; }