competitive-programming

Competitive Programmer's Core Skills by Saint Petersburg State University


Project maintained by claytonjwong Hosted on GitHub Pages — Theme by mattgraham

Week 1: Programming Competitions

Key Concepts

Resources

  1. Competitions
  2. Testing

Assignments

  1. Inventing Tests
  2. Addition and Subtraction
  3. Erasing Maximum
  4. Increment
  5. Straight Flush

Inventing Tests

def solve(a):
  max = 0
  for x in a:
    if x > max:
      max = x
  return max
def getTest():
  return [-1, -2, -3]
def solve(a):
  max = 0
  for i in range(len(a)):
    for j in range(len(a)):
      if i != j and a[i] + a[j] > max:
        max = a[i] + a[j]
  return max
def getTest():
  return [-1]
def solve(n):
  ans = 0
  for i in range(n):
    for j in range(n):
      if i < j and (i + j) % 2 == 0:
        ans += 1
  return ans
def getTest():
  return 100000
def solve(s):
  toDelete = s[0]
  others = ""
  for c in s:
    if c != toDelete:
      others += c
  s = others
  
  #prefix of length 1 surely doesn't contain different letters
  prefix = s[0]
  for i in range(1, len(s)):
    #each letter should be the same as the first
    if s[i] == prefix[0]:
      prefix += s[i]
    else:
      break
  return prefix
def getTest():
  return "aaaaa"

Addition and Subtraction

#include <iostream>

using namespace std;

int N = 2 * 1000; // 2 ops (add/sub) result in minimum "helpful" delta of 1 (ie. go 1 step closer to max target 1000)
int main() {
    auto add{ 0 }, sub{ 0 }, target{ 0 }, ans{ -1 };
    cin >> add >> sub >> target;
    for (auto i{ 0 }, x{ 0 }; i <= N; ++i) {
        if (x == target) {
            ans = i;
            break;
        }
        x += i % 2 == 0 ? add : -sub;
    }
    cout << ans << endl;
    return 0;
}

Erasing Maximum

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;

int main() {
    int N{ 0 }, del{ -1 };
    vector<int> A;
    cin >> N, copy_n(istream_iterator<int>(cin), N, back_inserter(A));
    for (auto i{ 0 }, max{ 0 }, cnt{ 0 }; i < N; ++i) {
        if (max < A[i])
            max = A[i], cnt = 0, del = i;
        if (max == A[i] && ++cnt == 3)
            del = i;
    }
    A.erase(A.begin() + del);
    copy(A.begin(), A.end(), ostream_iterator<int>(cout, " ")), cout << endl;
    return 0;
}

Increment

#include <iostream>
#include <algorithm>

using namespace std;

int main() {
    string S; cin >> S;
    auto N = all_of(S.begin(), S.end(), [](auto c) { return c == '9'; }) ? S.size() + 1 : S.size();
    cout << N << endl;
    return 0;
}

Straight Flush

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <unordered_set>
#include <cassert>

using namespace std;

int main() {
    int N{ 5 };
    vector<string> A; copy_n(istream_iterator<string>(cin), N, back_inserter(A));
    auto isSameSuit = [&](unordered_set<char> S = {}) {
        transform(A.begin(), A.end(), inserter(S, S.end()), [](auto& card) { return card[1]; });
        return S.size() == 1;
    };
    auto getValues = [&](bool aceHigh, vector<int> V = {}) {
        transform(A.begin(), A.end(), back_inserter(V), [=](auto& card) {
           auto val = card[0];
            if (isalpha(val)) {
                switch (val) {
                    case 'A': return aceHigh ? 14 : 1;
                    case 'K': return 13;
                    case 'Q': return 12;
                    case 'J': return 11;
                    case 'T': return 10;
                }
            }
            return val - '0';
        });
        return V;
    };
    auto isStraight = [=](auto& values) {
        assert(N == values.size());
        return N == 1 + *max_element(values.begin(), values.end()) // +1 for [i..j] inclusive
                      - *min_element(values.begin(), values.end());
    };
    auto hi = getValues(true),  // ace high
         lo = getValues(false); // ace low
    cout << (isSameSuit() && (isStraight(hi) || isStraight(lo)) ? "YES" : "NO") << endl;
    return 0;
}