📜 ⬆️ ⬇️

How I passed the test task for the summer internship in Yandex

image

Hi Habr, today I will talk about how I passed the test task for the summer internship at Yandex. This publication will be useful to novice developers, fans of Olympiad programming, those who are not indifferent to C ++ and Java, or just want to read an interesting article after a hard working day.

What to expect from this article?


Introduction


For those who are not familiar with the selection system for internships in Yandex, I will tell you briefly. On the Yandex site , a few months before the summer, a paid vacancy is announced for novice developers, in the department in which you would like to work (ie Yandex.Disk, Yandex.Alice). According to the link, you need to fill out a form, about where you study, what you do, what was your experience, what your thesis was written about and so on. After filling out the form, a test task is sent to your email, for which you have 6 hours to complete, any day during the week from the moment you received this letter.

It was difficult to choose this time, so I reached almost the last day. And all because I did not know what kind of test task I would expect. Googling a lot of articles, I did not find a single example or advice on what kind of tasks Yandex sets for its internships. That is why I decided to write this article. I will not give the correct solution to these problems, I will only provide what I managed to reach in the 6 hours allotted to me.
')
In the test task there were 6 tasks of different subjects, and different complexity. There were tasks for graphs, for lines, for dynamic programming, and Ad-Hoc for formatting time and floating-point numbers.

Task 1. Error


Job conditions
You maintain the site and monitor problems. The client received an error after trying to add his post to the system. You want to understand on which of the servers this error occurred.

There are n servers, the i-th of them accounts for ai percent of requests, of which bi percent ends with an error. For each server, find the probability that the error occurred on it.

Input format
The first line of the input file contains one integer n (1 ≤n≤ 100) - the number of servers.

Each of the next n lines contains two integers ai bi (0 ≤ ai, bi ≤ 100) - the probability that the request goes to the i-th server in percent and the probability that the i-th server will have an error in percent.

It is guaranteed that the sum of all ai is 100 and an error in the system can occur.

Output format
Print n lines. Each line should contain one real number (0 ≤ pi ≤ 1) - the probability that the error occurred on the corresponding server.

The absolute or relative error of each of the answers should not exceed 10-9.
Example 1
Input

2
50 1
50 2
Conclusion
0.333333333333
0.666666666667

Example 2
Input

3
10,100
30 10
60 2
Conclusion
0.704225352113
0.211267605634
0.084507042254

To solve this problem, I decided to use Java.

The operation algorithm is extremely simple: read a, b for n cases, multiply a and b , and save the result of the multiplication in arr [i], also sum the result into the total variable to calculate what is 100%.
For output, you just need to divide arr [i] by 100%

Decision
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Locale; import java.util.StringTokenizer; public class Main { public static void main(String[] args)throws IOException { Locale.setDefault(Locale.US);//     (0.3333,  0,333) String line; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //Buffered Reader     Scanner,      ,      StringTokenizer tk;//       int n = Integer.parseInt(br.readLine()); int arr[] = new int[n]; int total = 0; for(int i = 0; i< n;++i) { line = br.readLine(); tk = new StringTokenizer(line); int a = Integer.parseInt(tk.nextToken()); int b = Integer.parseInt(tk.nextToken()); arr[i] = (a*b); total += arr[i]; } for(int i = 0; i< n;++i) { System.out.printf("%.12f\n", (double)arr[i]/ total); } } } 


That's all, it was the first and last task that I was able to solve completely. The rest, unfortunately, did not have time, because I relaxed, thinking that all subsequent tasks would be on the same level. Alas, this was not the case. I will try to parse with you my code for the following tasks.

Task 2. Meetings


Job conditions
In order not to interfere with their colleagues in the workplace with loud discussions, the guys make appointments for a certain time and book negotiations. When booking, you must specify the date and time of the meeting, its duration and the list of participants. If one of the participants gets two meetings at the same time point, then the booking will be refused with an indication of the list of people whose time of the meeting overlaps with other meetings. You need to implement a prototype of such a system.

Input format
The first line of the input file contains one number n (1 ≤ n ≤ 1000) - the number of requests.

The following n lines contain queries, one per line. Requests are of two types:

APPOINT day time duration k names1 names2 ... namesk
PRINT day name
day - day number in 2018 (1 ≤ day ≤ 365)

time - meeting time, line in HH: MM format (08 ≤ HH ≤ 21, 00 ≤ MM ≤ 59)

duration - meeting duration in minutes (15 ≤ duration ≤ 120)

k - the number of participants in the meeting (1 ≤ k ≤ 10)

namesi, name - names of participants, strings consisting of small Latin letters (1 ≤ | name | ≤ 20). All colleagues have unique names. In addition, it is guaranteed that among the participants of one meeting no name appears twice.

Output format
If it was possible to make an appointment (the first type of request), output OK.

Otherwise, print in the first line FAIL, and in the next line, list the names of the participants for which the meeting time intersects with other meetings, in the order in which the names were given in the request, separated by spaces.

For the second type of requests, print for the given day and participant a list of all events at that time on that day in chronological order, one per line, in the format

HH: MM duration names1 names2 ... namesk

where the names of the participants follow in the same order as in the original description of the meeting. If there are no events on this day for this person, then nothing is needed.
Example 1
Input
7
APPOINT 1 12:30 30 2 andrey alex
APPOINT 1 12:00 30 2 alex sergey
APPOINT 1 12:59 60 2 alex andrey
PRINT 1 alex
PRINT 1 andrey
PRINT 1 sergey
PRINT 2 alex
Conclusion
Ok
Ok
FAIL
alex andrey
12:00 30 alex sergey
12:30 30 andrey alex
12:30 30 andrey alex
12:00 30 alex sergey

I spent a lot of time thinking about solving this problem, tried many options, but didn’t decide how best to pack time + day + number of people. I wanted to write struct {int day; int time_ms; string people [];}, but it would be inefficient to take up memory.

Another option was to present all days and times linearly, and create a structure (meeting) that stores three variables - the beginning of the meeting as (day * 24 * 60) (hour * 60 + minute), the end of the meeting (start + duration), the names of the people of this meeting . All objects of this structure can be packaged in a vector (vec). Then, when trying to make a new appointment, check if there are any meetings among those existing in the vector for which the following statement is true.
 vec[i] -> start<= meeting->start && vec[i] -> end >= meeting->start or vec[i] -> start <= meeting->end && vec[i] -> end >= meeting->end 

If yes, say that this time is busy, if not, add a new element to the vector.
I also tried to solve this problem with dict in Python, but realizing that I spent a lot of time, I switched to other tasks. I returned to this task literally 10 minutes before the end of 6 hours, when I almost had no strength to think, wrote that I had time and passed at least something. Probably, if I had worked out exactly the second solution to this problem, OnlineJudge would accept. But I passed the following Java code. You can safely skip it, it does almost nothing.

Decision
 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; public class p2 { public static void main(String[] args) throws IOException { String line; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer tk; long unixTime = System.currentTimeMillis() / 1000L; System.out.println(unixTime); int n = Integer.parseInt(br.readLine()); for (int i = 0; i < n; ++i) { line = br.readLine(); tk = new StringTokenizer(line, " :"); String cmd = tk.nextToken(); if (cmd.compareTo("APPOINT") == 0) { int day = Integer.parseInt(tk.nextToken()); int hour = Integer.parseInt(tk.nextToken()); int minute = Integer.parseInt(tk.nextToken()); int duration = Integer.parseInt(tk.nextToken()); int peopleN = Integer.parseInt(tk.nextToken()); String people[] = new String[peopleN]; for (int j = 0; j < peopleN; ++j) { people[j] = tk.nextToken(); } int start = (hour * 60) + minute; int end = start + duration; } } } } 


Task 3. Autocompletion


Job conditions
Arkady implemented an interactive system of autocompletion, which should allow him to quickly type texts of university works, including the diploma.

The system remembers all the words that already exist in the text. If Arkady dials the next word, the entered non-empty part of which coincides with the prefix of exactly one of the words already entered, after pressing a special key combination, the entered part can be instantly supplemented with the existing word.

For example, Arkady has already introduced the words of the thesis and autocompletion in various systems. Consider several options for the next word that he needs to enter:

  • Diploma - after the first character is entered, the system will offer to accept the completion of graduation auto completion, but it is not suitable;
  • work - after entering the first and second characters, the system will not offer anything, since There are two different words in the text that start with the current prefix, but after entering the third character, only one word remains (the proposed auto-completion should be accepted);
  • the difference is that again the option with auto-completion will appear only after entering the third character, but this time it is not necessary to accept the proposed option.

Arkady does not have the delete key for the entered characters, so he cannot delete characters from the text.

Arkady also decided that he would not use autocompletion if the proposed word is the beginning of the dialed, but does not completely coincide with it.

Help Arcadius determine how many times he will use the auto-completion function if he wants to minimize the number of keystrokes corresponding to the alphabetic characters.

Input format
The first line of the input data contains one integer n (1 ≤ n ≤ 100 000) - the number of words that Arkady intends to type. The second line contains n words si (1 ≤ | si | ≤ 1000). All words in the string consist only of lowercase English letters and are separated by single spaces.

The total length of all words does not exceed 1,000,000 characters.

Output format
In a single line print a single integer: the number of clicks on the letter keys on the keyboard.
Example 1
Input
3
hello world hello
Conclusion
eleven
Example 2
Input
five
an apple a big apple
Conclusion
13
Example 3
Input
five
aaaaa aaaab aaaaa abaaa abaaa
Conclusion
22

This task seemed to me much easier than it turned out to be in reality, sorry for the tautology. As a result, my decision was not complete - WA was released on the 14th test. Then I also spent a lot of time trying to understand where there could be a mistake, but I did not come to anything. I decided to write in C ++, because I thought that it would be easy to solve this problem using the set data structure.

Decision
 #include <iostream> #include <set> using namespace std; int main() { set<string> myset; string in; int n; cin >> n; int count = 0; for(int i = 0;i<n;++i) { cin>>in; if(myset.empty()) { count += in.length(); myset.insert(in); } else if(myset.find(in) != myset.end()) { //if a word is in set //check if other words in set contain similar chars //count += the greatest common subsequence int max = 0; for(auto e: myset) { int temp = 0; //case when entered sequence is less than element in set if(e == in) { ++count; } if(e.length() > in.length()) { for(int j = 0; j< in.length(); ++j) { if(e[j] == in[j]) { ++temp; } else { break; } } if(temp > max) { max = temp; } } else if(e.length() <= in.length() && e != in) { for(int j = 0; j< e.length(); ++j) { if(e[j] == in[j]) { ++temp; } else { break; } } if(temp > max) { max = temp; } } } count += max; } else if(myset.find(in) == myset.end()) { //case when entered word is not in the set count += in.length(); myset.insert(in); } } cout << count<<endl; return 0; } 


In general, this task can be divided into two big cases: a new word is introduced (word is not in the set) and a word is entered that has already been entered before (word in set).

The second case is broken up into several other cases, and it is checked that 1. there are words in set that start with the same characters (symbol) as our input word, 2. is our word a subsequence of some other word in set. As can be seen in the code, in each of the cases, a different number of keystrokes in the variable count are summed up.

Task 4. Team Building


Job conditions
Team building is a fun rafting event. Colleagues are actively involved in contests, quests, together overcome gaming difficulties. Sometimes people are so addicted that it is quite difficult to reorganize them for some kind of new activity. Right now, the presenter needs to break all the colleagues into two teams so that every two people in one team know each other well - and this is not an easy task.

You are given a graph in which exactly one vertex is associated with each person. The edge (u, v) means that the colleague u knows the colleague v well (and at the same time the colleague v knows the colleague u well). Check whether the vertices of the graph can be divided into two sets as required, and, if possible, output any suitable partition.

Input format
The first line contains two integers n and m (2 ≤ n ≤ 5000, 0 ≤ m ≤ 200000) - the number of vertices and the number of edges in the graph.

The next m lines contain descriptions of the edges - a pair of integers ab (1 ≤ a, b ≤ n, a ≠ b), which indicate the presence of an edge between the vertices a and b.

It is guaranteed that each pair of vertices is connected by no more than one edge, and that no vertex is connected to itself.

Output format
If it is impossible to split the vertices as required, output -1.

Otherwise, in the first line print the number k (1 ≤ k <n) - the number of vertices in one of the parts of the partition.

In the next line print k numbers - the vertices from this part of the partition.

In the next line print n - k numbers - vertices from the second part of the partition.

Each vertex must belong to exactly one of these parts.
Example 1
Input
3 1
12
Conclusion
2
12
3
Example 1
Input
thirty
Conclusion
-one

Here I already began to panic, and the confidence that I felt after solving the first task was dissolved without a trace. I did not know on which task to concentrate, and just tossing about the conditions of one or the other task. It took about 20 minutes to cope with the panic too. This is too much for solving contest problems.

Here I also decided to use set. Or rather, 3 Set'a: initial - where values ​​from 1 to n are stored, teamA, where the first links of the graph will be added, and teamB where the links that are not connected to teamA will be added, as well as all the remaining links in initial.

My algorithm is simple, but apparently Yandex was expecting more from me. WA on the third case.

decision
 #include<iostream> #include<set> using namespace std; int main() { int people; cin >>people; int pairs; cin >> pairs; set<int> initial; set<int> teamA; set<int> teamB; int a; int b; if(pairs == 0) { cout<<"-1"<<endl; } else { //fill set with people for(int i = 1;i<=people;++i) { initial.insert(i); } for(int i = 0;i<pairs;++i) { cin >> a; cin >> b; // case when a and b aren't in teamB if(initial.find(a) != initial.end() && initial.find(a) != initial.end() && !teamA.empty()) { teamB.insert(a); teamB.insert(b); initial.erase(a); initial.erase(b); } else if(teamB.find(a) == teamB.end() && teamB.find(b) == teamB.end()) { teamA.insert(a); teamA.insert(b); initial.erase(a); initial.erase(b); } else if ((teamA.find(a) != teamA.end() && teamB.find(b) != teamB.end()) or (teamA.find(b) != teamA.end() && teamB.find(a) != teamB.end())) { for(auto e: teamB) { teamA.insert(e); teamB.erase(e); } } } } cout <<"teamA"<< endl; for( auto e: teamA) { cout << e<<" "; } cout <<endl<<"teamB"<< endl; for( auto e: teamB) { cout << e<<" "; } cout << endl; return 0; } 


Task 5. Library


Job conditions
Kolya loves to read, and he would go to the library every day. By evening, he is satisfied only if he has read exactly one book more than yesterday. However, unfortunately, the library does not work on Saturdays and Sundays. Therefore, Kolya goes to it every working day and takes k books there at a time — no longer possible by the rules. However, Kohl is pleased that you can take new k books, even if you did not give away any books from those taken earlier. Kohl is also pleased that there is a stock of m books in his home library.

You know what day of the week is. Kohl recently got up and set out to read exactly one book today. How long Kolya can be satisfied if he goes to the library every time it is possible, starting today? We can assume that the stock of books in the library is endless.

Input format
The first line of the input file contains three integers k, m, d - the limit on the number of books that can be taken at the library per day, the number of books at Kolya’s house and the current day of the week (1 ≤ k ≤ 109, 0 ≤ m ≤ 109, 1 ≤ d ≤ 7). Saturday and Sunday are designated by numbers 6 and 7.

Output format
Output one number - the maximum number of days in the period during which Kolya can read so many books every day to be satisfied.
Example 1
Input
4 2 5
Conclusion
four
Example 2
Input
4 3 5
Conclusion
five

Solving this problem, I realized how much I miss
uDebug . My decision threw out WA on the 10th test.

Decision
 #include<iostream> using namespace std; int main() { int bks; cin >> bks; int lib; cin >> lib; int day; cin >> day; int total = bks + lib; int count = 0; int read = 0; while(true) { ++count; ++read; if(day>=1 && day <= 5) { total -= read; if(total == 0) { break; } else { total += bks; } } else if(day == 6) { total -= read; if(total == 0) { break; } } else if(day == 7) { total -= read; if(total == 0) { break; } day = 0; } ++day; } cout << count; return 0; } 


Task 6. Mobilization


I basically did not pass this task during the contest. I wrote the code only to read and output. After completion of the contest, I disassembled all tasks except this one. To be honest, I still can not understand what needs to be done. I will be glad to any of your comments.

Job conditions
In Yandex, the project "Mobilization" starts again! The company is recruiting n young people who are passionate about mobile development for a three-month training. At the beginning of the project, a test was conducted, where the skill of participant i in development was evaluated as ai, and the skill in management was evaluated as bi.

At the time of the project, participants need to be divided into two equal by the number of participants in the team - developers and managers. It is planned to do this in such a way as to maximize the total benefits brought by all participants. If the participant gets the role of the developer, his benefit will be equal to ai, otherwise - bi.

But even those involved in the project, the participants find time to gain new knowledge! Sometimes participants bring certificates of completion of courses, where it is said that the skill of participant i in development or management has increased by di. In such a case, it may be beneficial to re-form teams to maximize the total benefit (equal team sizes must be maintained).

Your task is to help Yandex and, after reviewing each new certificate brought by the participant, count the current total benefit of the teams.

Input format
The first line of the input file contains the number n (2 ≤ n ≤ 2 105, n is even) - the number of project participants. The second line sets n integers ai (0 ≤ ai ≤ 109) - the skills of each of the participants in the design. The next line in the same format sets the skill of the participants in the control bi (0 ≤ bi ≤ 109).

The next line contains an integer m (1 ≤ m ≤ 105) - the number of certificates brought by participants. Each of the following m lines contains three integers numi, typei, di (1 ≤ numi ≤ n, 1 ≤ typei ≤ 2, 1 ≤ di ≤ 104) - participant number, type of increased skill (1 - development, 2 - control) and the value of the increase in the corresponding skill.

Output format
After processing each request for a new certificate, output the current total benefit of all participants.
Example 1
Input
four
7 15 3 4
10 10 0 6
3
1 1 4
4 1 6
2 2 10
Conclusion
34
35
43

The code that I managed to write
 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; public class p6 { public static void main(String[] args)throws IOException { String line; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer tk; int n = Integer.parseInt(br.readLine()); int a[] = new int[n]; int b[] = new int[n]; tk = new StringTokenizer(br.readLine()); int aSum = 0; for(int i = 0;i<n;++i) { a[i] = Integer.parseInt(tk.nextToken()); aSum += a[i]; } int bSum = 0; for(int i = 0;i<n;++i) { b[i] = Integer.parseInt(tk.nextToken()); bSum += b[i]; } } } 


The result


Overall, I enjoyed this experience. A little sad that I could not give everything to the fullest. But then, now I know what tasks for an internship at Yandex are, and after reading this article, you also know. I hope this article was interesting and at least a little useful for you. I will be sincerely welcome any comments and advice. At the time of writing this article, I also expected that you would share your solutions to these problems, which probably arose in your head, or on paper while reading the conditions.

Thanks to all!

Source: https://habr.com/ru/post/353662/


All Articles