Conquering Keokradong LightOJ 1048
一道lightoj 上的题目,我是在上次的一次练习赛中做到的,那时候两个半小时之后就只剩下两题了,而且两题原理是一样的,超开心,结果看了半个小时后这题,一句话:没思路。然后打酱油了。。。囧。
好吧,昨天学二分的时候突然思路来了,果断把那时候还有一题(LightOJ 1076 Get the Containers)给戳掉了。然后么,在这题的打印上又卡了好长时间,,,我好弱啊。。。囧。
好吧,思路就是二分:
//Danceonly #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int INF = 100000007; #define MIN(a,b) (a > b ? b : a) #define MAX(a,b) (a > b ? a : b) int aa[10005]; int N,M; bool Find(int x) { int t = x; int cnt = 1; for (int i=0;i<N;i++) { if (x < aa[i])return 0; if (t - aa[i] >= 0)t -= aa[i]; else {t = x - aa[i];if (++cnt > M)return 0;} } if (cnt <= M)return 1; else return 0; } void Print(int x) { int cnt = 0; for (int i=0;i<N;i++) { if (aa[i]+aa[i+1] > x || N - i == M - cnt){printf("%d\n",aa[i]);cnt++;} else aa[i+1] += aa[i]; } } int main() { int T; scanf("%d",&T); for (int c=1;c<=T;c++) { int sum = 0; int max_n = 0; scanf("%d%d",&N,&M); N++; M++; for (int i=0;i<N;i++) { scanf("%d",&aa[i]); if (max_n < aa[i])max_n = aa[i]; sum += aa[i]; } if (N == M) { printf("Case %d: %d\n",c,max_n); for (int i=0;i<N;i++)printf("%d\n",aa[i]); continue; } int r = max_n; int l = sum; int mid; while (l - r >= 1) { mid = (l+r)/2; if (Find(mid)) l = mid; else r = mid + 1; } while (Find(mid) == 0)mid ++; printf("Case %d: %d\n",c,mid); Print(mid); } return 0; }