Hi, I wanted to show you guys simple chatbot that I had written. It can message you list of live competitions going on codechef and hackerearth.
https://github.com/g4ur4v/HackerListMessengerBot
Feedback welcome.
Hi, I wanted to show you guys simple chatbot that I had written. It can message you list of live competitions going on codechef and hackerearth.
https://github.com/g4ur4v/HackerListMessengerBot
Feedback welcome.
Is there a simpler way than taking the whole string as input and then separating all of them? Have been searching for a while and can't find a shorter way. I have T lines and they can have any number of values. These values can be negative also. Thanks.
Editorialist: Lalit Kundu
CAKEWALK
Sorting
Given N dolls of size A1, A2 ... AN.
A Matryoshka doll refers to a set of wooden dolls of strictly decreasing size, placed one inside the other. Any doll can contain only one doll directly inside it.
Output "YES" if it is possible to nest them all and have one doll on the outside and "NO" otherwise.
If any two dolls have same size, we can never nest them together. Otherwise, we just sort them in decreasing order and nest them.
So, we just have to check if there are any two numbers same in a list.
We can do this in many ways:
1. sort and check adjacent elements. Complexity: O(N log N)
2. check for each pair of i,j if Ai == Aj. Complexity: O(N * N)
3. Mark flag[Ai], for all i and check each element of flag array. Complexity: O(MAX[Ai]).
4. Use set from STL in C++ and keep inserting in order. If same element find already answer is NO. Complexity: O(N log N).
Author:Sunny Aggarwal
Tester:Sergey Kulik
Editorialist:Sunny Aggarwal
Cakewalk
Implementaion, Mathematics, Brute Force.
You are given a number $N$ that represents the number of coins you have and you have to print the maximum possible height $H$ of triangle which can be made from these coins in such a way that $i^{th}$ row of the triangle contains $i$ coins.
Maximum possible height of the triangle is the maximum possible value of $H$ such that $\frac{H\times(H+1)}{2} \le N$.
It should be noted that $i^{th}$ row of triangle contains $i$ coins. Therefore, a traingle with $H$ height will contain $1$ coin in $1^{st}$ row, 2 coins in $2^{nd}$ row, ... , $H$ coins in $H^{th}$ row and total number of coins required to build a triangle of height $H$ will be equal to
$$\sum_{\substack{1 \le i \le H}}{i} \quad = \quad \frac{H \times (H+1)}{2}$$
As we are asked to find the maximum possible height of the triangle, we have to find the maximum value of $H$ such that $\frac{H \times (H+1)}{2} \le N$. Note that the value of $N$ ~= $10^9$ in worst case and therefore the maximum possible value of $H$ will be order of $\sqrt{N}$.
We can use following simple procedure to solve this problem.
int sum(int h) { return (h * (h+1) / 2); }void solve() { int n; cin >> n; int h = 1; while(sum(h) <= n) { h ++; } cout << h - 1 << "\n"; }
$O(\sqrt{N})$
Try solving same problem with $1 \le N \le 10^{15}$.
Author's solution can be found here.
Tester's solution can be found here.
Author:Vineet Paliwal
Tester:Roman Rubanenko
Editorialist:Jingbo Shang
Easy
Fibonacci Property, Quick Sort, Offline Algorithm, Hash, Binary Search
Given T big integers with at most D digits, determine whether it can be a fibonacci number. The total digits are L.
There are a number of ways to solve this problem.
If you look up fibonacci properties online, you may find the followings: n is a fibonacci number if and only if 5 * n * n + 4 or 5 * n * n - 4 is a perfect square number. Using this property, together with big integer multiplication and sqrt, you can get the answer.
However, this method is too complex to pass this problem. It is worth noting that fibonacci number increases exponentially. And thus, there are only O(D) fibonacci numbers have at most D digits. This observation gives us the intuition to solve this problem much simpler.
The fist method is an offline version. First, we load all queries and sorted them. This step will take O(TDlogT) if we use quick sort. Second, we compute fibonacci numbers one after another using big integer addition. For each fibonacci number, check its relationship with the current smallest query number:
If the they are same, then the answer of that query is YES and let’s look at the next query number; If the fibonacci number is smaller, then let’s look at the next fibonacci number; if the fibonacci number is larger, then the answer of that query is NO and let’s look at the next query number.
This procedure needs O((D + T)D) time. Therefore, this offline version’s time complexity is O(TDlogT + (D + T)D).
The second one involves hash. We can simply generate O(D) fibonacci number and only restore the remainder of some relatively big number, for example, 2^64 or 10^9+7. And then, check the query number’s remainder to see whether it occurred using hash table or tree set. Suppose we use hash table, the time complexity is O(D + L).
Author's solution can be found here.
Tester's solution can be found here.
SIMPLE
Ad-hoc
Given integers N and K, pick K integers in 1...N, such that no two chosen integers are relatively prime.
Let us try to construct a set of K integers such that no two are coprime. If we choose a number x (>1), and pick all multiples of x, then clearly no two of them will be coprime (all the numbers are divisible by x)! Thus, we can pick a set of size floor(N/x) having such a property. Thus, it is in our interest to have x small.
Indeed, if we pick x = 2, then for any K<= floor(N/2), we can just output the set 2, 4, 6, ..., 2K. Hence, we have the sufficient condition when K<= floor(N/2).
It turns out that this sufficient condition is also necessary (almost). The fact is, when K> N/2, any set of size K will have some 2 consecutive elements. These consecutive elements will then be coprime.
The only special case is where (N, K) = (1, 1). In this case, since K = 1, we can output plate 1 and we're done.
Formally, we can prove the necessity as follows:
If K = 1, we output 1 and we are done.
If K> 1, then we can can never have 1 in our set.
Then, from (2i, 2i+1), we can pick only one of the two. That is, we can pick only one from (2, 3), (4, 5), ..., which gives us the bound of floor(N/2).
Can be found here
Can be found here
Author:Sunny Aggarwal
Tester:Sergey Kulik
Editorialist:Sunny Aggarwal
Easy
Sorting, Greedy, Data Structure, Implementation.
Given an array $A$ containing $N$ positive integers and an integer $K$. We are asked to report the largest $K$ values from the list of sums of all possible subarrays of array $A$.
Subtask 1
Listing sums of all the possible subarrays of $A$ and finding the largest $K$ values will be enough to pass this subtask.
C++ Code
#define ll long long void solve(int N, int K, int *arr) { vector<ll> sum; for(int i=1;i<=n;i++) { long long int s = 0; for(int j=i;j<=n;j++) { s += arr[j]; sum.push_back(s); } } sort(sum.rbegin(), sum.rend()); for(int i=0; i<=K-1; i++) cout << sum[i] << " "; cout << "\n"; }
Time Complexity
$O((\frac{N \times (N+1)}{2})) \times \log{\frac{N \times (N+1)}{2}})$
Note
Although the above solution will get passed on first subtask but we can have slight better complexity by maintaining a priority queue for the first $K$ elements instead of sorting all the sums.
It is easy to see that the above solution will time out for this subtask.
Then, how to approach it ?
It can be noticed that the largest and first value will always be sum of all the elements as it is given that all elements are positive integers. It means the sum is corresponding to the subarray $[1 to N]$ inclusively. Now, we have taken up the range $1...N$ and we can see that the next possible largest sum will be the maximum of sum of range $2...N$ and range $1...N-1$. Let us assume that the second largest is obtained from the range $1...N-1$. Then, the third largest sum will be maximum of sum of range $2...N$ ( previous range left ), range $2...N-1$ and range $1...N-2$ ( new ranges ). The above procedure can be run $K$ times to find the largest $K$ values.
How to implement above idea ?
Let us maintain a priority queue $S$ ( set can also be used in C++ ). So, whenever we are taking the sum of a range say [L to R] from S, we can simply insert 2 new values to $S$ i.e sum of range $[L+1 to R]$ and $[L to R-1]$ if $L != R$. Note that along with sum of range we are also maintaining the indices i.e $L$ and $R$ denoting that range in our priority queue.
C++ Code
#define ll long long void solve(int N, int K, int *arr) { set<pair<ll,pair<int,int>> S; long long int prefix_sum[N+1]; for(int i=1;i<=n;i++) { prefix_sum[i] = prefix_sum[i-1] + arr[i]; } S.insert({prefix_sum[N], {1, N}}); while( K -- && !S.empty() ) { pair<ll,pair<int,int>> top = *S.begin(); S.erase( top ); long long int sum; int L, R; sum = top.first; L = top.second.first; R = top.second.second; cout << sum <<" "; if( L != R ) { S.insert({sum-arr[L], {L+1, R}}); S.insert({sum-arr[R], {L, R-1}}); } } }
$O(K \times \log{K})$
Author's solution can be found here.
Tester's solution can be found here.
Hi all, I need your help to make a list of most used data structures and algorithms along with their tutorials, implementation and some problems on them. It will be helpful to everyone in many ways. I request everyone to contribute to this list by providing links to tutorials, problems, etc. I will keep updating this list regularly.
Binary Search :Tutorial, Problems, Tutorial, Implementation, Problem
Quicksort :Tutorial, Implementation, Tutorial
Merge Sort :Tutorial, Implementation, Tutorial
Suffix Array :Tutorial, Tutorial, Implementation, Tutorial, Implementation, Problem, Problem
Knuth-Morris-Pratt Algorithm (KMP) :Tutorial, Tutorial, Implementation, Tutorial, Problem
Rabin-Karp Algorithm :Tutorial, Implementation, Tutorial, Problem, Problem
Tries :Tutorial, Problems, Tutorial : I,II, Tutorial, Problem, Problem, Problem
Depth First Traversal of a graph :Tutorial, Impelementation, Tutorial, Problems, Problem, Problem, Problem
Breadth First Traversal of a graph :Tutorial, Impelementation, Tutorial, Problems, Problem, Problem, Problem, Flood Fill
Dijkstra's Algorithm :Tutorial, Problems, Problem, Tutorial(greedy), Tutorial (with heap), Implementation, Problem, Problem
Binary Indexed Tree :Tutorial, Problems, Tutorial, Original Paper, Tutorial, Tutorial, Problem, Problem,Problem, Problem, Problem, Problem, Problem
Segment Tree (with lazy propagation) :Tutorial, Implementation, Tutorial, Tutorial, Problems, Implementation, Tutorial, Implementation and Various Uses, Persistent Segment Tree, problems same as BIT, Problem, Problem/HLD is used as well/
Z algorithm :Tutorial, Problem, Tutorial, problems same as KMP.
Floyd Warshall Algorithm :Tutorial, Implementation, Problem, Problem
Sparse Table(RMQ) :Tutorial, Problems, Tutorial, Implementation(C++), Java implementation
Heap / Priority Queue / Heapsort :Implementation, Explanation, Tutorial, Implementation, Problem, Chapter from CLRS
Suffix Automaton :Detailed Paper, Tutorial, Implementation (I), Tutorial, Implementation (II), Problem, Problem, Problem, Problem, Tutorial, Implementation
Lowest Common Ancestor :Tutorial, Problems, Paper, Paper, Problem, Problem, Problem
Counting Inversions :Divide and Conquer, Segment Tree, Fenwick Tree, Problem
Suffix Tree :Tutorial, Tutorial, Intro, Construction : I, II, Implementation, Implementation, Problem, Problem, Problem, Problem
Dynamic Programming : Chapter from CLRS(essential), Tutorial, Problems, Problem, Problem, Problem, Problem, Tutorial, Problem, Problem, Problem, Longest Increasing Subsequence, Bitmask DP, Bitmask DP, Optimization, Problem, Problem, Problem, Problem, Problem, Problem, Problem, DP on Trees : I, II
Basic Data Structures :Tutorial, Stack Implementation, Queue Implementation, Tutorial, Linked List Implementation
Graphs :Definition, Representation, Definition, Representation, Problem, Problem
Minimum Spanning Tree :Tutorial, Tutorial, Kruskal's Implementation, Prim's Implementation, Problem, Problem, Problem, Problem, Problem
Combinatorics :Tutorial, Problems, Problem, Tutorial
Union Find/Disjoint Set :Tutorial, Tutorial, Problems, Problem, Problem, Problem
Knapsack problem :Solution, Implementation
Aho-Corasick String Matching Algorithm :Tutorial, Implementation, Problem, Problem, Problem, Problem
Strongly Connected Components :Tutorial, Implementation, Tutorial, Problem, Problem, Problem
Bellman Ford algorithm :Tutorial, Implementation, Tutorial, Implementation, Problem, Problem
Heavy-light Decomposition :Tutorial, Problems, Tutorial, Implementation, Tutorial, Implementation, Implementation, Problem, Problem, Problem
Convex Hull :Tutorial, Jarvis Algorithm Implementation, Tutorial with Graham scan, Tutorial, Implementation, Problem, Problem, Problem, Problem, Problem
Line Intersection :Tutorial, Implementation, Tutorial, Problems
Interval Tree :Tutorial, Implementation, Problem, Problem, Problem, Problem, Problem, Problem, Tutorial
Network flow :(Max Flow)Tutorial : I,II, Max Flow(Ford-Fulkerson) Tutorial, Implementation, (Min Cut) Tutorial, Implementation, (Min Cost Flow)Tutorial : I,II,III, Dinic's Algorithm with Implementation, Max flow by Edmonds Karp with Implementation, Problem, Problem, Problem, Problem, Problem, Problem, Problem, Problem, Problem, Problem, Problem, Problem, Problem, Problem, Problem
K-d tree :Tutorial, Tutorial, Implementation, Problem
Binary Search Tree :Tutorial, Implementation, Searching and Insertion, Deletion
Quick Select :Implementation, Implementation
Treap/Cartesian Tree :Tutorial(detailed), Tutorial, Implementation, Uses and Problems, Problem, Problem
Game Theory :Detailed Paper, Tutorial, Problems, Grundy Numbers, Tutorial with example problems - I,II,III,IV, Tutorial, Problems, Problem, Problem, Problem, Problem, Problem, Problem, Problem, Problem, Problem, Problem, Problem, Nim
STL (C++) :I,II, Crash Course
Manacher's Algorithm :Implementation, Tutorial, Tutorial, Implementation, Tutorial, Implementation, Problem, Problem, Problem
Detecting Cycles in a Graph : Directed - I, II Undirected : I
Backtracking :N queens problem, Tug of War, Sudoku
Eulerian and Hamiltonian Paths :Tutorial, Tutorial, (Eulerian Path and Cycle)Implementation, (Hamiltonian Cycle)Implementation
Graph Coloring :Tutorial, Implementation
Meet in the Middle :Tutorial, Implementation
Johnson's Algorithm :Tutorial, Tutorial, Implementation
Maximal Matching in a General Graph :Blossom/Edmond's Algorithm, Implementation, Tutte Matrix, Problem
Recursion : I,II, Towers of Hanoi with explanation
Link-Cut Tree :Tutorial, Wiki, Tutorial, Implementation, Problem, Problem, Problem, Problem
Euler's Totient Function :Explanation, Implementation, Problems, Explanation, Problems
Edit/Levenshtein Distance :Tutorial, Introduction, Tutorial, Problem, Problem
Mo's Algorithm : Tutorial and Problems
Author:Sergey Kulik
Testers:Kevin Atienza and Vasya Antoniuk
Translators:Sergey Kulik (Russian), Team VNOI (Vietnamese) and Hu Zecong (Mandarin)
Editorialist:Kevin Atienza
Easy
Maximum Subarray Sum
Given an array $A[1\ldots N]$, what is the maximum subarray sum you can get by removing at most one element?
For every position $i$, compute the maximum subarray sum that ends in position $i$. Call it $E[i]$.
For every position $i$, compute the maximum subarray sum that starts in position $i$. Call it $S[i]$.
Both can be done in $O(N)$ using Kadane's algorithm/dynamic programming.
The answer is the largest among the following values:
Let's first answer a simpler question: What is the maximum subarray sum of the array (without any removals)? This is actually a standard problem and you might already be familiar with it, but let's describe it anyway.
Here's a naïve solution (in pseudocode):
answer = -INFINITY
for j=1..N:
current = 0
for i=j..1 by -1:
current += A[i]
answer = max(answer, current)
It simply tries out all subarrays. Unfortunately, this is slow; it runs in $O(N^2)$ time, and for $N \approx 10^5$ this will not pass the time limit.
To improve this solution, notice that we don't have to check all the subarrays that end at $j$. We can classify all such subarrays into two types: whether it has length $1$ or length greater than $1$.
That last part is crucial; if you study the code above more closely, notice that what we're computing is, for every possible rightmost index $j$, the maximum subarray sum that ends in $j$. And we're doing this in increasing order of $j$. Thus, when we're trying to compute it for $j$, we already have the answer for $j-1$, so we don't need a loop any more!
The following code illustrates it better:
answer = -INFINITY
current = 0
for j=1..N:
current = max(A[j], current + A[j])
answer = max(answer, current)
Notice that before the line current = max(A[j], current + A[j])
, the variable current
contains the maximum sum that ends in $j-1$. Thus, current + A[j]
is the maximum sum of any subarray that ends in $j$ with length greater than $1$.
This is now much faster: it runs in $O(N)$ time! Also, if you're curious, this algorithm is actually famous and has a name: Kadane's algorithm.
Implementation notes:
current
and answer
will exceed the bounds for 32-bit integers. So you should use 64-bit variables (long long
in C/C++, long
in Java). INFINITY
, you can use a very large number that will exceed all finite numbers under consideration. Since the maximum absolute sum is only $10^5\cdot 10^9 = 10^{14}$, an INFINITY
value of, say, $10^{18}$ is good enough for our purposes!Now, let's answer the original problem, where you are allowed to remove at most one element from the array. We already know the answer when you don't remove any element, so all that remains it to compute the answer if we remove exactly one element. The maximum among these two is the answer. More specifically,
Then the answer is $\max(M_0, M_1)$. We already know $M_0$ from above, so all that remains is computing $M_1$.
Obviously, we can try removing each element in turn, and computing the maximum subarray sum, and obtaining $M_1$ as the maximum among all these maximums. But this takes $O(N^2)$ time which is too slow. We will need a better algorithm.
Suppose we remove the element $A[i]$. Then there are only three possible cases for the maximum subarray sum:
But here's an important observation: in the first two cases, the subarrays are actually also subarrays of the original array, which means their sums cannot be more than $M_0$. And since we're trying to maximize the answer and we alreaady know that the answer is $\ge M_0$, we can safely ignore these cases!
So all that remains is computing the maximum sum of any subarray that contains $A[i-1]$ and $A[i+1]$ (ignoring $A[i]$ of course). We can decompose such a subarray into two parts:
These two subarrays don't overlap, so in order to maximize the sum, we want to maximize them individually. But we have already computed all maximum subarray sums that end in every position, from the previous algorithm! So if we just store the partial results that we got, then we can answer the first part quickly!
In more detail, let $E[i]$ be the maximum subarray sum that ends in $A[i]$. We can compute $E[1\ldots N]$ using the previous algorithm:
answer = -INFINITY
current = 0
for j=1..N:
current = max(A[j], current + A[j])
answer = max(answer, current)
E[j] = current
Similarly, we can define $S[i]$ to be the maximum subarray sum that starts at $A[i]$. Computing $S[1\ldots N]$ by performing the algorithm in reverse, as in the following:
current = 0
for j=N..1 by -1:
current = max(A[j], current + A[j])
answer = max(answer, current)
S[j] = current
With arrays $S[1\ldots N]$ and $E[1\ldots N]$, we can now compute the maximum sum of any subarray that contains $A[i-1]$ and $A[i+1]$, assuming $A[i]$ is removed: It is simply $E[i-1] + S[i+1]$!
for i=2..N-1:
answer = max(answer, E[i-1] + S[i+1])
By combining all these snippets, we now have the answer to the problem!
$O(N)$
EASY
Prime factorization, Sieve
Find the number of integers in the given range which have prime number of divisors.
Although L and R can be as high as 10^12 but R-L is <= 10^6, this allows us to iterate through the complete range and count the number of divisors of each number in the range.
Approach 1:
If a number N is divisible by D then either it has 2 factors(D and N/D) or it is square of D. Another thing to note is that if a number has 2 divisors x and y such that x < y, then x < sqrt(N) and y > sqrt(N). Using these 2 facts we can iterate through all the numbers in range [1, sqrt(R)] and count the number of factors for each of the number.
Working commented solution follows:
bool isPrime[10000];
void init()
{
// Since range is very small so not used Sieve
for (int i = 2; i < sizeof(isPrime); ++i) {
int j = 2;
for (; j * j <= i; ++j) {
if (i % j == 0) {
break;
}
}
if (j * j > i) isPrime[i] = true;
}
}
main()
{
init();
int testCases, divisors[1000005];
scanf("%d", &testCases);
while(testCases--) {
long long L, R;
scanf("%lld%lld", &L, &R);
for(long long i=L; i<=R; i++) divisors[i-L] = 0; //Initialize divisors of all numbers to 0
for(long long i=1; i*i <= R; i++) { // Iterate through 1 to sqrt(R)
long long square = i*i;
// j starts with first number in range [L, R] which is multiple of i
for(long long j=( (L-1) / i + 1) * i; j <= R; j += i) {
// Factors under consideration are i and j / i
if (j < square) continue; // Already counted because of 2 in else condition below
if( square == j ) // Just 1 factor
divisors[j-L] += 1;
else divisors[j-L] += 2; // Counting factors i and j / i
}
}
int ans = 0;
for(long long i = L; i <= R; i++) if(isPrime[divisors[i-L]]) ans++;
printf("%d\n",ans);
}
}
Approach 2:
This approach is taken by more coders including tester.
This is based on prime factorization of a number and then counting the total number of divisors.
Lets take an example:
Consider prime factors breakdown of 18 (2^1 * 3^2) so total number of factors are (1+1) * (2 + 1) = 6 [Factors: 1, 2, 3, 6, 9, 18]. Similarly if a number is p1^x1 * p2^x2 * p3^x3 * … then total number of factors is (x1+1) * (x2+1) * (x3+1) * …
Now if we generate all primes <= 10^6 using sieve and later use them to find out how many times it goes into each number in the given range, we know the number of divisors composed of primes <= 10^6. We may have missed 1 prime number > 10^6 which might have fallen in the range as range goes as high as 10^12. But we are sure that there is only 1 such prime! So if we detect this case we can simply multiply our number of factors calculated so far by (1+1). See tester’s solution for working code.
Author's solution will be uploaded soon
Tester's solution can be found here and here
It would be helpful if the author/Editorialist/admin could put up the editorial for the above problem.
I have no idea how to solve this question. codechef.com/problems/A6. I can't find the solution anywhere and haven't got a reply from any forum for it till now@admin, help
I request the author/tester to put up an editorial for the problem. Also, the problem statement is not properly written. It should clearly specify that all the square plots must be of the same size.
The problem statement is ambiguous and leads many users to submit a wrong solution. Please correct this and provide an editorial.
Recently I asked a question and found that the formatting of code is not the same as source. The newlines and tabs are not showing correctly. I tried but didn't find a solution. Is there any problem from your side or I'm not getting it right..?
#include<iostream>
using namespace std;
void input(int,double);
void check(int ,double);
int main()
{
int c1;
double c2;
cin>>c1>>c2;
if(c1 > c2 )
{
cout<<c2<<endl;
}
else
{
input(c1,c2);
}
return 0;
}
void input(int c, double d)
{
if( (0 < c && c<=2000) && (0<=d && d <= 2000) )
{
check(c,d);
}
else
{
cout<< d<<endl;
}
}
void check(int a,double b)
{
if(a%5!=0)
{
cout<< b<<endl;
}
else
{
double c;
c=((b-a)-0.5);
cout<< c<<endl;
}
}
this code compiles perfectly but its shows me wrong answer plsrectify the error in my algorithm
Author:Istvan Nagy
Tester:Kevin Atienza and Gedi Zheng
Editorialist:Kevin Atienza
Ad hoc, string processing
In table tennis, a game is won by the player first scoring 11 points except in the case when both players have 10 points each, then the game shall be won by the first player subsequently gaining a lead of 2 points.
Given a valid, finished game in which Chef is one of the players, determine if Chef won.
There are many solutions. Here are a few simple ones:
Solution 1: Print "WIN" if the last character in $S$ is a '1', otherwise print "LOSE".
Solution 2: Print "WIN" if there are more 1s than 0s in $S$, otherwise print "LOSE".
This is a simple problem. First, note that the sequence of results of the matches is valid and finished. This means that the winner has been determined at the end (and only right after the last match), and the winner has a lead of at least two points from the loser. This means the following:
The last match is won by the overall winner of the contest.
At the end, the winner has won more matches than the loser, and so all we have to do is to check if Chef has won more matches than his opponent!
But each of these facts give us an algorithm to compute the answer!
Here is an implementation of the first algorithm, in C++:
#include <iostream>
#include <ios>
using namespace std;
int main() {
ios::sync_with_stdio(false);
int z;
cin >> z;
while (z--) {
string s;
cin >> s;
cout << (s[s.length()-1] == '1' ? "WIN\n" : "LOSE\n");
}
}
and in Python:
for cas in xrange(input()):
print "WIN" if raw_input()[-1] == '1' else "LOSE"
There's also a one-liner code-golf in Python:
print'\n'.join(["LOSE","WIN"][input()&1]for _ in range(input()))
Also, here is an implementation of the second algorithm, in C++:
#include <iostream>
#include <ios>
using namespace std;
int main() {
ios::sync_with_stdio(false);
int z;
cin >> z;
while (z--) {
string s;
cin >> s;
int total = 0;
for (int i = 0; i < s.length(); i++) {
total += s[i] - '0';
}
cout << (total * 2 > s.length() ? "WIN\n" : "LOSE\n");
}
}
and in Python:
for cas in xrange(input()):
s = raw_input()
print "WIN" if 2*sum(map(int, s)) > len(s) else "LOSE"
Let's consider a follow-up problem. Suppose that Chef and his opponent continued after the winner has been determined, i.e. assume there are matches after the winner has been determined.
In this case, we cannot do the strategies above anymore, because it might happen that the Chef lost the game, but his opponent didn't take the following matches seriously so Chef won a lot of matches afterwards. In this case, we now have to determine at which point the winner has been determined, and stop there. We just have to remember that the winner has been determined if someone has scored at least 11 points and has gained a lead of at least two against the other opponent.
Here's an implementation in C++:
#include <iostream>
#include <ios>
#include <algorithm>
using namespace std;
int main() {
ios::sync_with_stdio(false);
int z;
cin >> z;
while (z--) {
string s;
cin >> s;
int s0 = 0, s1 = 0;
for (int i = 0; i < s.length(); i++) {
(s[i] == '1' ? s1 : s0)++;
if (max(s0, s1) >= 11 and abs(s0 - s1) >= 2) break;
}
cout << (s1 > s0 ? "WIN\n" : "LOSE\n");
}
}
and in Python:
for cas in xrange(input()):
s = [0,0]
for c in map(int, raw_input()):
s[c] += 1
if max(s) >= 11 and abs(s[0] - s[1]) >= 2:
break
print "WIN" if s[1] > s[0] else "LOSE"
$O(|S|)$
Author:Sunny Aggarwal
Tester:Sergey Kulik
Editorialist:Mugurel Ionut Andreica
CAKEWALK
None
Chef has N rooms, each of them painted in one of 3 colors (R, G or B). He wants to repaint the minimum number of rooms such that, in the end, all the rooms have the same color.
Paint all the rooms in the color which appears the largest number of times (of course, rooms which already have that color will not be repainted).
Repainting the minimum number of rooms is equivalent to not repainting (i.e. keeping the initial color in) the maximum number of rooms. Since all the rooms must have the same color in the end, this means that we should find the color C in which the most rooms are painted and then repaint all the rooms which have a color other than C in color C.
In order to count how many rooms of each color we have, we can simply maintain three variables cntR, cntG and cntB. Then we traverse the string denoting the colors of the rooms and increment the corresponding variable depending on the color denoted by the current character in the string.
Time complexity: O(N).
Author's solution can be found here.
Tester's solution can be found here.
I would like to delete my CodeChef user name/ account, please let me about the same ?
Authors:Jaub Safin
Testers:Vasya Antoniuk
Translators:Vasya Antoniuk (Russian), Team VNOI (Vietnamese) and Hu Zecong (Mandarin)
Editorialist:Praveen Dhinwa
Simple
Simple observations, dp
An array is called alternating if any two consecutive numbers in it have opposite signs (i.e. one of them should be negative, whereas the other should be positive).
You are given an array $A$ of size $N$ consisting of non-zero elements. For each index $i$ from $1$ to $N$, you have to find the length of longest subarray starting at $i$.
We can observe that if an array is alternating, then all of its subarrays are also alternating.
So, we can divide the array into maximal alternating subarrays. For doing that, we will iterate over array from left to right, if the sign of current number is different than previous number, then this number can be used to extend previous alternating subarray, Otherwise we will have to start constructing a new maximal alternating subarray.
In this way, we can partition the array into various maximal alternating subarrays.
After this, finding length of longest subarray starting at index $i$ is quite easy, as it can be done easily by finding the position of $i$ in the corresponding maximal alternating subarray. If $p$ be position and $L$ be the length of the maximal subarray, then $L - p + 1$ will be the length of longest subarray starting at index $i$.
Observation 1:
Values of the number don't matter, only their signs do.
So, we can change the array $A$ such that it consists of -1 and 1's only.
Observation 2:
If an array $A$ is alternating, then all of it's subarrays are alternating.
Let us take an example to understand how we can apply the above observation to solve the problem.
Let $A = [1, 1, -1, 1, 1, -1, -1]$
So, we start from $A_1$ and note that $A_1$ is equal $A_2$.
So the maximal subarray starting from $1$ will be $[1]$ itself.
Now, we go to $A_2$, we can see that $A_2, A_3, A_4$ have different signs, and $A_4$ has same sign as $A_5$.
So the maximal subarray starting from index $2$ will be [1, -1, 1].
So, we break the array into several parts such that each part is maximal alternating subarray. In our example, the parts will be
[1] [1, -1, 1] [1, -1], [-1]
We can formalize the above idea to write a pseudo code to break an array into various parts of maximal alternating subarrays.
vector<vector<int> > parts;
vector<int> curPart;
subpart.push_back(a[0]);
for (int i = 1; i < n; i++) {
// If signs of current and previous number are different,
// then it means that we can extend the current part.
if (a[i] * a[i - 1] == -1) {
curPart.push_back(a[i]);
} else {
// We add the curPart into parts.
parts.push_back(curPart);
}
}
// Check at the end whether the curPart has non-zero length or not.
// If it has, then add curPart into parts.
if (curPart.size() > 0) {
parts.push_back(subpart);
}
Now, let us find the length of longest alternating subarray ending at each index $i$ for our example subarray $A$.
We get [1] [3, 2, 1], [2, 1], [1]
So, this means that for an maximal alternating subarray of length $L$, the answers (length of longest alternating subarray start from that index) will be $L, L-1, \dots, 1$.
We can use this idea to solve our problem.
// i denotes the current index of array at which we currently are.
int i = 1;
for (vector<int> curPart : parts) {
int L = curPart.size();
while (L > 0) {
answer[i] = L;
// increment i
i++;
// decrement L
L--;
}
}
// Note the fact that we didn't use the explicit values of curPart, only its size matter.
You can also solve the problem by a very simple dp.
Let $len[i]$ denote the maximum length of alternating subarray starting at position $i$.
We can observer that if $a[i]$ and $a[i + 1]$ has opposite signs, then $len[i]$ will be $1$ more than $len[i + 1]$.
Otherwise in the case when they have same sign, then $len[i]$ will be just $1$.
len[N] = 1;
for (int i = N - 1; i >= 1; i--) {
// a[i] and a[i + 1] have different signs.
// Note that the a[i] can go upto 10^9,
// So if a is stored in int data type, then the a[i] * a[i + 1] might not fit in int.
// So, we cast it to long long
if (a[i] * (long long) a[i + 1]< 0) {
len[i] = len[i + 1] + 1;
} else {
len[i] = 1;
}
}
As we have seen in both the solutions we have to iterate over the array $A$ only once or constant number of times. So, time complexity of the algorithm will be $\mathcal{O}(N)$ which will easily fit in time with $N = 10^5$ and $T = 10$.
with the help of combinations function from this module we can find the different combinations of elements and find the prod of elements in that tuple and hence return the max prod.