Written by alex.velea, August 10th, 2018.

Last update on August 12th, 2018.

The 25th Central European Olympiad in Informatics

will take place in Warsaw, Poland, during August 12th-18th 2018. The most gifted high school students from 14 countries will have the opportunity to prove their knowledge and skills in informatics.

The CS Academy team will organise the online mirror for this year's competition.

The online mirrors will take place right after the finish of each of the 2 competition days, having the same scoring format.

The online mirror schedules are the following:

  • Day 1 - 14th August 2018 13:00 UTC
  • Day 2 - 16th August 2018 13:00 UTC

If you're participating in CEOI

@alex.velea will be the Deputy Leader for Romania's delegation. Just drop by and say hello for a cool sticker or just for a good talk.

Contest format

  • The contest will be rated for all users
  • You will have to solve 3 tasks in 5 hours.
  • There will be full feedback throughout the entire contest.
  • The tasks will have partial scoring. The maximum score for each problem will be 100 points.
  • There will be a time tie breaker, so two users having the same total score at the end of the contest will be further sorted by the penalty.
  • The penalty will be equal to the first time they achieved the final score. Only submissions that increase the total score are taken into account. This means that after getting 50 points on a problem you will still have 50 points even after submitting a solution that gets 0 points and that the penalty will remain the same.
Continue reading
Written by mihaic, November 13th, 2017.

Last update on November 13th, 2017.

Hey everyone,

Hope you noticed that we made some changes to the platform since the last contest. Here's the summary:

Task + Workspace

The biggest change involves the task page. It's probably the most used functionality in the entire website, to be able to solve problems, and it needed a bit of an improvement.

We've increased the usable space, both vertically and horizontally, without giving up any of the functionality. Plus it looks a lot cooler now.

We've also tried to make it easy for people that closed the workspace that they need to open it at least if they want to submit.

We hope to have some improvements to the workspace itself soon.

Submissions

Each submission is now opened in a modal dialogue by clicking on it, since the old collapsible interface made it annoying to see a source for instance in the chat or inside any other narrow section. Each submission now also has a permanent link, which you can access by clicking on the job id.

Various performance improvements and bug fixes

We had some server performance issues on round 52, which we could only fix then. We somehow managed to DDOS ourselves from workspaces saving the current source. Normally it's not an issue, if this load is evenly spread, but we managed to synch them all to simultaneously save every 30 seconds, at the exact same time. This actually happened just because we optimized the broadcast of tasks to take less than a second to most users.

In the end we just added some random offset for each user, and we know now we'd be ready to handle 10k simultaneous users, with maybe just a resize of our web server.

Let us know what you think about the changes with a comment here.

Continue reading
Written by mihaic, September 8th, 2017.

Last update on September 15th, 2017.

Hey guys, it's been a while since the last time we had a new CS Academy platform version.

It's fitting that for the element with the largest number of compounds we're introducing a fully configurable themes. Right now you can only configure the most important colors and the website font, most of the rest being based on these. We'll soon add predefined themes and more options.

I've also previously talked about our open source code, and which we're now releasing as a full stack solution, if you want to build a web app, with frontend and backend that includes all the parts of CS Academy that you could reuse in another project. I'll write a follow-up blog post in the next few days, with a walk-through tutorial on how to use it.

We want to find out how we can best improve our platform, so please answer the questionnaire below help us do this:

Some personal thoughts on the competitive programming community

I've been thinking recently about this topic, and how this community can leave it's greatest impact on society.

Competitive programmers have done some impressive things. Examples include Quora co-founder and ex-Facebook CTO Adam D'Angelo, Ethereum inventor Vitalik Buterin and more recently Jakub Pachoki (meret)'s contribution to building a world class AI, that beat the best humans at Dota2.

Overall, I think the awesome talent in this community can accomplish even greater things. The greatest challenges I see are organizational though. I know how hard it was for me to get into software development coming as a self-taught programmer. I had great self-doubt that I could be a developer for a while, mostly because of how intimidating it was to be completely unknowing at "real world" coding, which made want even more to do the thing I was good at: writing a C++ program that read some input and writes some output.

Understanding that maintainable and easy to read code is more important than almost everything else was something that took me a long time to internalize.

It's also a lot harder to stay focused for longer periods of time after getting used to solving algorithmic challenges. Before you got a feeling of accomplishment every time you solved a problem or understood a new algorithm/data structure. In complex software projects you may need to carry on for days or weeks at a time without receiving that endorphin kick, and you just need to

Worst of all was figuring out this transition on my own. It's a lot better now, with online tutorials, yet very few of them try to help you with the needed mentality change, just focusing on teaching you syntax. In writing the tutorial for our open-source framework, I really hope to address this as well.

We want to make CS Academy into the best platform you can build, to help the community of algorithmics enthusiasts fulfill their potential. Please help us by answering the questionnaire above and letting us know in what directions we could work with the community to better it.

Continue reading
Written by alex.velea, September 5th, 2017.

Last update on September 13th, 2017.

The first edition of EJOI (European Junior Olympiad in Informatics) will be taking place in Sofia, Bulgaria.

The first contest will be on 9 September and the second one on 11 September.

We'll like to wish good luck to all participants attending the competition.

If you have any pieces advice for the young contestants, please leave them below

Prior to the competition we held a contest, Junior Challenge, as a preparation for the main contest.

This wouldn't be possible without the help of bciobanu, Andrei1998, tamio, costin_andrei and george_stelian who prepared all the problems for Junior Challenge.

Here are the cumulated results for day 1 and day 2.

The results are based on users who put EJOI in their name. If you see someone who participated at Junior Challenge and will go to EJOI but it's not here, will gladly add him/her in the scoreboard.

RankUserTotalDay 1Day 2

1

300iq

800

400

400

2

egor.lifar

660

360

300

3

georgerapeanu

640

340

300

4

ppavic

590

360

230

5

krešimir nežmah

585

340

245

6

Sonechko

565

340

225

7

Tiberiu Musat

545

300

245

8

Nazik_number_one

540

240

300

9

nikab

530

300

230

10

toloraia

505

340

165

11

MKopchev

495

240

255

12

dorijanlendvaj

485

240

245

13

StroustrupEJOI

485

240

245

14

Karasick

485

240

245

15

MiricaMatei

470

240

230

16

Sorting

450

220

230

17

limunada

430

200

230

18

dobito6

425

260

165

19

Charis02

415

170

245

20

donentseto

410

260

150

21

aeyakmimkayea_EJOI

400

200

200

22

tinca_matei

390

240

150

23

MvC

390

240

150

24

toonewbie

340

240

100

25

evpipis

330

180

150

26

ioane

290

145

145

27

IhateProgramming

235

0

235

28

anpans

220

125

95

29

Blagojce

205

105

100

30

dsekerov

190

60

130

31

eugenb

180

105

75

32

eynizademurad

170

40

130

33

KonstantinKamenov

155

5

150

34

computerbox

150

20

130

35

SamAnd

150

0

150

36

Abelyan

130

130

0

37

giorgikob

110

0

110

38

hankag

100

55

45

39

cfalas

65

65

0

40

azategaEJOI

60

60

0

41

Andres Alumets

52

25

27

42

thearn2002_EJOI

40

40

0

43

mikhail.yumanov

40

40

0

44

kiko0202_EJOI

40

40

0

45

thanos

38

0

38

46

Znalix_EJOI

10

10

0

47

Adrian_EJOI

10

10

0

48

MagaknutoEJOI

5

5

0

49

patriK2_EJOI

0

0

0

50

grg.lcrr

0

0

0

51

artyoma02

0

0

0

52

VargaBalazs.EJOI

0

0

0

53

AzizHuseynov_EJOI

0

0

0

Continue reading
Written by wefgef, July 20th, 2017.

Last update on July 20th, 2017.

After two consecutive Div. 2 contests, we hosted another Div. 1 + Div. 2. The hard problems of the round were authored by tourist. We'd like to thank him for all the effort he's put into preparing the tasks.

The notoriety of the author attracted a large number of people, and once again, we broke the records of registered users and users who submitted at least one solution. Over 500 people managed to solve at least one problem.

Initially, we were planning on having a regular round with 7 problems and a constest duration of 2 hours. While preparing Tree Anitchain (Hard), tourist thought it's a really nice problem to ask for any valid permutation, not necessarily the first lexicographical one. This is how Tree Antichain (Easy) was born. We decided to increase the contest duration to 2 hours and 30 minutes. It's interesting to note that the best strategy was to jump straight to the hard version, and then just submit the same code for the easy one. However, only 8 out of the 24 users who solve both did this. Missing on the optimal strategy didn't stop user-2726 from winning, though.

The second hardest problem, Parallel Lines, was solved by 10 people, indicating a harder than usual task. Many others had lots of wrong submissions, hoping to exploit potentially weak tests. This was not the case, as tourist spent a lot of effort in order to fail wrong probabilistic solutions.

The last problem, Checkroom Hooks, was really hard, with only 2 accepted solutions. Besides user-2726 and user-3479, user-3237 was really close to solving it too (he would've won the contest).

We hope you had a great time participating. Congratulations to the winners:

  1. user-2726
  2. user-3237
  3. user-1749
  4. user-2816
  5. user-3924

We also chose the winners of the random prizes: csacademy.com/code/e7HBBEHv

Congrats user-8123 for winning 50$ or a CS Academy t-shirt and user-4010 for winning a Skype lesson with user-2724!

Here are the solutions of the tasks:

Shoe Pairs

Solution

For each size between 11 and 100100 we can count how many left shoes and right shoes we have. The number of pairs of a certain size we can make is equal to the minimum of these two values.

Official implementation

Attack and Speed

Solution

Let's say we are going to spend NN of the KK dollars to increase the attack. Then A+NX=S+(KN)YA + N * X = S + (K - N) * Y, so N=S+KYAX+YN = \frac{S + K * Y - A}{X + Y}. We have a solution if this value is an integer in [0,K][0, K].

Another solution is to binary search the value of NN. For a fixed value, if the final A<SA < S, we need to increase NN, otherwise decrease it.

Official implementation

Editorial solution:

Solution using binary search:

Bounded Difference

Solution

Let's call conflict a pair of adjacent elements such that AiAi+1>K|A_i - A_{i+1}| > K. If we swap two elements with indices ii and jj we can only solve conflict between AiA_i or AjA_j and their neighbours. So there are at most 44 conflicts we can solve.

We can start by identifying all the initial conflicts. If there are more than 44, we have no solution. If there is no conflict, the array is obviously valid. Otherwise, let's say we take the first conflict between AiA_i and Ai+1A_{i+1}. One of these two elements should be involved in the swap. We can take one of them and check all the N2N-2 possibilities. There are a two things we need to check:

  • The swap doesn't create new conflicts
  • The initial conflicts are solved

Official implementation

Tree Antichain (Easy)

Solution

There is no solution if the tree is a star, because the internal vertex neighbours all the N1N-1 leaves.

In all the other cases, it is possible to build a solution. Suppose we color the vertices black and white such that there is no edge connecting vertices of the same color. Because a tree is bipartite, we can always find such a coloring.

If we just print all the white vertices, followed by all the black vertices, the only potential pair of adjacent vertices that can be connected by an edge is the last white vertex and the first black one. So if we can find one pair of white and black vertices that are not connected, we can build a solution. If the graph is not a star, it must contain some path of length 3\geq 3. On such a path, the first vertex and the last vertex of opposite color don't share an edge.

Official implementation

Path Union

Solution

Let's analyse an easier version of this problem, where the only nodes we can select are leaves. Let's say we have K=2NK = 2^N leaves and we label them from 00 to K1K-1, from left to right.

If we are allowed to select only 11 leaf, we can choose any of them. If we are allowed to choose 22 leaves, one of them should be from the first half, the other one from the second half. If we can choose 44 leaves, each of them should be from a different quarter. In general, if we can select 2X2^X leaves, we divide the leaves in buckets of size K2X\frac{K}{2^X} and we can take a leaf from each bucket. If the number of leaves is not a power of two, we can build the solution for the closest power of two. Then we eliminate some of the selected leaves until we are left with the desired number of nodes.

In the general case where we can select nodes of different depths, we can use the same principle. We start building the solution from the leaves and move up towards the root. Let's say we've selected the leaves, and we want to select the nodes at depth N1N-1. There's no point to select the parents of the selected leaves, as they will not mark any extra edges. Even more, if the leaves were from distinct buckets of size 2X2^X, their parents will be from distinct buckets of size 2X12^{X-1}. If there are any buckets of size 2X12^{X-1} that don't contain any parent, we can use them to select the nodes of the current depth. If we are still allowed to select some extra nodes for the current depth, we can split all the buckets in half and select a node from each half that doesn't contain an already selected node or a parent. We can repeat this step while necessary, until we select all the nodes at the current depth or we hit the limit.

Official implementation

Editorial implementation:

Another approach, which sets nodes from top to bottom

Tree Antichain (Hard)

Solution

As you can read in the editorial for the easy version, we have a solution if the graph is not a star.

Now let's say we chose a prefix A1,A2,...AKA_1, A_2, ... A_K of the permutation and we want to check if it's possible to build a solution starting with this prefix. It turns out we can always do this if by removing vertices A1,A2,...AKA_1, A_2, ... A_K the remaining graph is not a star. Let's prove this:

We color the vertices in black and white, so no two neighbouring vertices have the same color. Assuming that AKA_K's neighbours are black, if the graph is not connected, we can just choose all the white vertices, followed by all the black vertices, making sure the adjacent white and black pair is made up of vertices from different components. If the graph is connected (but not a star), we again choose all the white vertices followed by the black ones and we'll always find a pair of vertices of different colors that don't share an edge.

Knowing this, we can just build the solution incrementally. At each step we maintain a set of all the available vertices, and try to append them to the solution in increasing order. We can check if the remaining graph is not a star by maintaining a multiset of degrees - the largest degree should be less than the number of remaining vertices minus 11.

A careful implementation is needed to avoid O(N2)O(N^2) complexity.

Official implementation

Parallel Lines

Solution

If N2KN \leq 2*K, there is a simple O(N2hashset)O(N^2 * \text{hashset}) solution. Consider the slopes of all lines passing through two points. For each slope, we have several pairs of points (edges in a future graph) which belong to the same line of that slope. Then, the number of connected components in the graph is the answer for this slope.

Otherwise, if N2KN \geq 2*K, consider the multiset of slopes of all lines passing through two points out of the first 2K2*K points. The best slope appears at least KK times in this multiset. Since we have K(2K1)K*(2*K-1) slopes in total, we have only at most 2K12*K-1 candidate slopes. We can check each of these explicitly to get an O(NKhashset)O(N*K * \text{hashset}) solution.

Official implementation

Checkroom Hooks

Solution

Suppose we wish to simulate the process. Let's maintain a set of segments of free hooks between every two neighboring occupied hooks. For a segment ss of k(s)k(s) consecutive free hooks, consider the value of d(s)=(k(s)+1)/2d(s) = (k(s) + 1) / 2 (integer division) which is the distance from a center hook of this segment to the closest occupied hook. A new person chooses a random center hook inside some segment with the largest d(s)d(s). Note that if k(s)k(s) is even, then there are two center hooks for segment ss.

This simulation will be correct until every free hook has a neighboring occupied hook. After that, every person just chooses a random remaining hook. From now on we'll disregard this final phase of the process, but it's fairly easy to account for.

Time for an important observation. Suppose person ii is choosing a segment randomly from the set s1,s2,...,smis_1, s_2, ..., s_{m_i}, where mi>1m_i > 1. Then, independent of person ii's choice, person i+1i+1 will have to choose one of the remaining segments in this set, that is, they will have mi1m_i - 1 options. The same applies to person i+2i+2 if mi>2m_i > 2, and so on.

Note that segments of even and odd length in the same set have different probabilities to be chosen, though. Segments of even length have two center hooks, so they are more probable to be chosen.

Let f(neven,nodd,t)f(n_{even}, n_{odd}, t) be the probability that if there are nevenn_{even} segments of even length and noddn_{odd} segments of odd length in some set, then a center hook of an odd-length segment will be chosen on step tt of removing elements from this set. The values of ff can be easily calculated with dynamic programming.

Using the values of ff, now we can find the probabilities of different hooks chosen on different steps of our non-deterministic process. The solution goes as follows.

Every time, we find the set of segments ss with the largest d(s)d(s). Then, if this set contains mim_i segments, we can calculate the required probabilities for the next mim_i steps.

But here comes trouble. Segments of even length have two center hooks, and we don't know which one is occupied, so we can't deterministically move on with the simulation!

Here comes the final twist. In case of even-length segments, simply pretend that the leftmost center hook is always chosen. In fact, this might not be true. But if the rightmost center hook was chosen, the situation would be symmetric with regard to the center of the segment. So once we have found the probabilities for all the remaining steps for hooks inside this segment, make these probabilities symmetric!

For example, suppose we had a segment consisting of hooks 1 through 6, and after step ii we pretend to have taken hook 3. As we continue, we find the probabilities aj,1,...,aj,6a_{j,1}, ..., a_{j,6} for all j>ij > i. Then, we replace aj,1a_{j,1} and aj,6a_{j,6} with (aj,1+aj,6)/2(a_{j,1} + a_{j,6}) / 2, and do the same with aj,2a_{j,2} and aj,5a_{j,5}, and with aj,3a_{j,3} and aj,4a_{j,4}.

Overall, the solution works in O(n3)O(n^3) due to the number of states in ff, but it's very fast in practice. Solutions with better asymptotics are possible, but not required.

Hope you enjoyed the contest, good luck next time!

Continue reading