diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ce0b9d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +in +out \ No newline at end of file diff --git a/.vscode/pascal b/.vscode/pascal new file mode 100644 index 0000000..47ee667 Binary files /dev/null and b/.vscode/pascal differ diff --git a/.vscode/pattern b/.vscode/pattern index 26da68f..b9c926e 100644 Binary files a/.vscode/pattern and b/.vscode/pattern differ diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..cb996a9 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "iostream": "cpp" + } +} \ No newline at end of file diff --git a/.vscode/square b/.vscode/square new file mode 100644 index 0000000..f719622 Binary files /dev/null and b/.vscode/square differ diff --git a/in b/in index e69de29..ee66e7d 100644 --- a/in +++ b/in @@ -0,0 +1,11 @@ +4 +1 1 +15 +3 3 +1 1 1 +1 2 1 +1 1 1 +1 3 +3 1 2 +1 3 +1 2 3 \ No newline at end of file diff --git a/pascal.cpp b/pascal.cpp index fd3b99d..f61f4b1 100644 --- a/pascal.cpp +++ b/pascal.cpp @@ -4,40 +4,35 @@ using namespace std; int main() { if (fopen("in", "r")) freopen("in", "r", stdin), freopen("out", "w", stdout); - int T; - cin >> T; - for (int t = 0; t < T; ++t) { - int N; - cin >> N; - cout << "Case #" << t + 1 << ":\n"; - if (N <= 500) { - for (int i = 0; i < N; ++i) cout << i + 1 << " " << 1 << '\n'; - } - else { - N -= 32; - int sum = 0; - bool side = 0; - for (int i = 0; i < 32; ++i) { - cout << i + 1 << " " << (side ? i + 1 : 1) << '\n'; - if (N & (1 << i)) { - if (side) { - for (int j = i; j > 0; --j) cout << i + 1 << " " << j << '\n'; - side = 0; - } - else { - for (int j = 2; j <= i + 1; ++j) cout << i + 1 << " " << j << '\n'; - side = 1; - } - sum += (1 << i); - } + int T; + cin >> T; + for (int t = 0; t < T; ++t) { + cout << "Case #" << t + 1 << ":\n"; + + int N; + cin >> N; + if (N <= 500) { + // if N <= 500 then just use naïve method + for (int i = 0; i < N; ++i) cout << i + 1 << " " << 1 << '\n'; + } + else { + // first we try to make N - 32 + int sum = 0, side = 0, goal = N - 32; + for (int i = 0; i < 32; ++i) { + cout << i + 1 << " " << (side ? i + 1 : 1) << '\n'; + + // each row sums to 2 ^ (i + 1) + // check if goal has a 2 ^ (i + 1) in its binary representation + if (goal & (1 << i)) { + // walk across the row + for (int j = 1; j <= i; ++j) cout << i + 1 << " " << (side ? i - j + 1 : j + 1) << '\n'; + side = !side; // toggle the side + sum += (1 << i); + } else ++sum; - } - int x = 32; - N += 32; - while (sum < N) { - cout << x + 1 << ' ' << (side ? x + 1 : 1) << '\n'; - ++x, ++sum; } - } - } + + for (int i = 32; sum < N; ++i, ++sum) cout << i + 1 << ' ' << (side ? i + 1 : 1) << '\n'; + } + } } \ No newline at end of file diff --git a/pattern.cpp b/pattern.cpp index 192c691..dea6915 100644 --- a/pattern.cpp +++ b/pattern.cpp @@ -2,40 +2,49 @@ using namespace std; int main() { - if (fopen("in", "r")) freopen("in", "r", stdin), freopen("out", "w", stdout); + if (fopen("in", "r")) freopen("in", "r", stdin), freopen("out", "w", stdout); int T; cin >> T; - for (int t = 0; t < T; ++t) { + for (int t = 1; t <= T; ++t) { + cout << "Case #" << t << ": "; + int N; cin >> N; string P[55]; for (int i = 0; i < N; ++i) cin >> P[i]; - string a, b, c; - bool found = 1; - for (int i = 0; i < N && found; ++i) { - vector v; - v.push_back(""); + string l, m, r; // left, middle, end parts of final answer + bool ans = 1; // flag so we can quickly break when no solution exists + for (int i = 0; i < N && ans; ++i) { + // tokenize string + vector parts; + parts.push_back(""); for (auto& c : P[i]) { - if (c == '*') v.push_back(""); - else v.back() += c; + if (c == '*') parts.push_back(""); // add new string + else parts.back() += c; // add c to current string } - for (int j = 0; j < v.front().size() && found; ++j) { - if (j >= a.size()) a.push_back(v.front()[j]); - else if (v.front()[j] != a[j]) found = 0; + + string& s = parts.front(); // leftmost part + for (int j = 0; j < s.size() && ans; ++j) { + if (j >= l.size()) l.push_back(s[j]); // extend l + else if (s[j] != l[j]) ans = 0; // s doesn't match with current l } - reverse(v.back().begin(), v.back().end()); - for (int j = 0; j < v.back().size() && found; ++j) { - if (j >= c.size()) c.push_back(v.back()[j]); - else if (v.back()[j] != c[j]) found = 0; + + s = parts.back(); // rightmost part + reverse(s.begin(), s.end()); + for (int j = 0; j < s.size() && ans; ++j) { + if (j >= r.size()) r.push_back(s[j]); // extend r + else if (s[j] != r[j]) ans = 0; // s doesn't match with current r } - for (int j = 1; j < v.size() - 1; ++j) b += v[j]; + + // add other parts to the middle string + for (int j = 1; j < parts.size() - 1 && ans; ++j) m += parts[j]; } - reverse(c.begin(), c.end()); - cout << "Case #" << t + 1 << ": "; - if (found) cout << a << b << c << '\n'; - else cout << "*\n"; + reverse(r.begin(), r.end()); + + // Creates at most 2 * 99 + 50 * 98 = 5098 < 1e4 characters + cout << (ans ? l + m + r : "*") << '\n'; } } \ No newline at end of file diff --git a/square.cpp b/square.cpp index bc63ef1..91552c2 100644 --- a/square.cpp +++ b/square.cpp @@ -5,26 +5,27 @@ typedef long long ll; int main() { if (fopen("in", "r")) freopen("in", "r", stdin), freopen("out", "w", stdout); - int T; - cin >> T; - for (int t = 0; t < T; ++t) { - int R, C; - cin >> R >> C; + int T; + cin >> T; + for (int t = 0; t < T; ++t) { cout << "Case #" << t + 1 << ": "; - - vector> S(R); - set> check; - vector> rs(R), cs(C); + + int R, C; + cin >> R >> C; + vector> S(R); // we have to use vector of vector because R or C could be 1e5 + set> check; // set of candidate competitors to check + vector> rs(R), cs(C); // sets to quickly determine a competitor's neighbors ll ans = 0, sum = 0; for (int i = 0; i < R; ++i) { - S[i].resize(C); - for (int j = 0; j < C; ++j) { + S[i].resize(C); + for (int j = 0; j < C; ++j) { cin >> S[i][j]; - check.emplace(i, j); sum += S[i][j]; + check.emplace(i, j); } - } + } + // prepare sets for (int i = 0; i < R; ++i) { for (int j = 0; j < C; ++j) rs[i].insert(j); } @@ -33,45 +34,51 @@ int main() { } while (1) { - vector> elim; - for (auto& x : check) { - int i = x.first, j = x.second; - if (S[i][j]) { - int cnt = 0, num = 0; - auto r = cs[j].find(i); - if (r != cs[j].end()) { - if (r != cs[j].begin()) cnt += S[*(--r)][j], ++num, ++r; - if (r != --cs[j].end()) cnt += S[*(++r)][j], ++num; - } - auto c = rs[i].find(j); - if (c != rs[i].end()) { - if (c != rs[i].begin()) cnt += S[i][*(--c)], ++num, ++c; - if (c != --rs[i].end()) cnt += S[i][*(++c)], ++num; - } - if (num * S[i][j] < cnt) elim.emplace_back(i, j); + vector> elim; // vector to store eliminated competitors + for (auto& x : check) { // examine every candidate competitor + int i = x.first, j = x.second, cnt = 0, num = 0; + + auto r = cs[j].find(i); + if (r != cs[j].end()) { // get neighbors + if (r != cs[j].begin()) cnt += S[*prev(r)][j], ++num; + if (r != --cs[j].end()) cnt += S[*next(r)][j], ++num; } + + auto c = rs[i].find(j); + if (c != rs[i].end()) { // get neighbors + if (c != rs[i].begin()) cnt += S[i][*prev(c)], ++num; + if (c != --rs[i].end()) cnt += S[i][*next(c)], ++num; + } + + if (num * S[i][j] < cnt) elim.emplace_back(i, j); } - check.clear(); + + check.clear(); // clear check for finding candidates for next round ans += sum; + for (auto& x : elim) { int i = x.first, j = x.second, cnt = 0, num = 0; sum -= S[i][j]; S[i][j] = 0; + auto r = cs[j].find(i); - if (r != cs[j].end()) { - if (r != cs[j].begin()) check.emplace(*(--r), j), ++r; - if (r != --cs[j].end()) check.emplace(*(++r), j); + if (r != cs[j].end()) { // get neighbors + if (r != cs[j].begin()) check.emplace(*prev(r), j); + if (r != --cs[j].end()) check.emplace(*next(r), j); } + auto c = rs[i].find(j); - if (c != rs[i].end()) { - if (c != rs[i].begin()) check.emplace(i, *(--c)), ++c; - if (c != --rs[i].end()) check.emplace(i, *(++c)); + if (c != rs[i].end()) { // get neighbors + if (c != rs[i].begin()) check.emplace(i, *prev(c)); + if (c != --rs[i].end()) check.emplace(i, *next(c)); } - rs[i].erase(j); - cs[j].erase(i); + + rs[i].erase(j), cs[j].erase(i); // remove competitor from sets } + if (elim.empty()) break; } - cout << ans << '\n'; - } + + cout << ans << '\n'; + } } \ No newline at end of file