/* * ComponentCheckingzeil.cpp * * Created on: Sep 26, 2012 * Author: zeil */ #include #include #include #include #include using namespace std; const int Limit = 100000; int maxReviewersNeeded; int componentCount[Limit]; // if k==componentCount[i], then there are k components that still need to have i+1 reviewers int countDiff[Limit]; // countDiff[i] indicates the number of components currently requiring i+1 reviewers that are // about to get a reviewer (and so will be moved down to componentCount[i-1] void readComponents (istream& in, int n) { fill_n (componentCount, Limit, 0); fill_n (countDiff, Limit, 0); maxReviewersNeeded = -1; int total = 0; while (total < n) { string line; getline(in, line); int c, numComponents; istringstream lineIn (line); lineIn >> c; if (!(lineIn >> numComponents)) numComponents = 1; componentCount[c-1] += numComponents; maxReviewersNeeded = max(maxReviewersNeeded, c); total += numComponents; } } /** * We have numEngineers, each of whom can review e components. * Assign them to the components requiring the most reviewers. */ int assignReviewers (int e, int numEngineers) { int lastChange = maxReviewersNeeded + 1; for (int j = 0; j < numEngineers; ++j) { int i = maxReviewersNeeded; int duties = e; while (i > 0 && duties > 0) { if (componentCount[i-1] - countDiff[i-1] > 0) { ++countDiff[i-1]; --duties; lastChange = min(lastChange, i); } --i; } } return lastChange; } /** * We have marked one or more components as having been assigned reviewers. * For each such component, decrement the number of reviewers needed and * shift its count lower in the array * */ void reassessComponents(int lastAssigned) { int i = maxReviewersNeeded; int carry = 0; while (i >= lastAssigned || carry > 0) { componentCount[i-1] += carry - countDiff[i-1]; carry = countDiff[i-1]; countDiff[i-1] = 0; if (i == 1) carry = 0; --i; } while (maxReviewersNeeded > 0 && componentCount[maxReviewersNeeded-1] == 0) --maxReviewersNeeded; } bool processEngineers (istream& in, int m) { int total = 0; while (total < m) { string line; getline(in, line); int e, numEngineers; istringstream lineIn (line); lineIn >> e; if (!(lineIn >> numEngineers)) numEngineers = 1; int lastAssigned = assignReviewers (e, numEngineers); reassessComponents(lastAssigned); } return (maxReviewersNeeded == 0); } void solveDataSet (istream& in, int n, int m) { readComponents (in, n); bool solved = processEngineers (in, m); cout << ((solved) ? "1" : "0") << endl; } void run (istream& in) { int m, n; while (true) { in >> n >> m; if (n > 0 && m > 0) solveDataSet (in, n, m); else break; } } int main (int argc, char** argv) { if (argc > 1) { ifstream in (argv[1]); run(in); } else run (cin); return 0; }