2002. Тестовое задание
Условие
Это было обычное хмурое октябрьское утро. Небо было затянуто тяжёлыми серыми тучами, накрапывал дождь. Капли падали на стёкла автомобилей, били в окна домов. Илья сидел за компьютером и угрюмо взирал на унылый пейзаж за окном. Внезапно его взгляд привлекла надпись, появившаяся в правом нижнем углу экрана: «You have 1 unread email message(s)». Заранее приготовившись удалить бесполезный спам, Илья открыл письмо. Однако оно оказалось куда интереснее…
Вас приветствует отдел по работе с персоналом компании «Рутнок БКС»!
Мы рассмотрели вашу заявку на вакансию разработчика программного обеспечения и были заинтересованы вашей кандидатурой. Для оценки ваших профессиональных навыков мы предлагаем вам выполнить несложное тестовое задание: необходимо реализовать систему регистрации для форума. Она должна поддерживать три операции:
- «register username password» — зарегистрировать нового пользователя с именем «username» и установить для него пароль «password». Если такой пользователь уже есть в базе данных, необходимо выдать ошибку «fail: user already exists». Иначе нужно вывести сообщение «success: new user added».
- «login username password» — войти в систему от имени пользователя «username» с паролем «password». Если такого пользователя не существует в базе данных, необходимо выдать «fail: no such user». Иначе, если был введен неправильный пароль, нужно выдать «fail: incorrect password». Иначе, если пользователь уже находится в системе в данный момент, необходимо вывести «fail: already logged in». Иначе нужно вывести сообщение «success: user logged in».
- «logout username» — выйти из системы пользователем «username». Если такого пользователя не существует, необходимо вывести «fail: no such user». Иначе, если пользователь не находится в системе в данный момент, следует выдать «fail: already logged out». Иначе необходимо выдать сообщение «success: user logged out».
Пользуйтесь этим письмом как формальным описанием алгоритма и строго соблюдайте порядок обработки ошибок. Желаем вам удачи!
И вот Илья, откинув все дела, уже решает тестовое задание. Попробуйте и вы выполнить его!
Исходные данные
В первой строке дано целое число [latex]n[/latex] — количество операций [latex]\left( 1 \leq n \leq 100 \right)[/latex]. В каждой из следующих [latex]n[/latex] строк содержится один запрос в соответствии с форматом, описанным выше. В качестве «username» и «password» могут выступать любые непустые строки длиной до [latex]30[/latex] символов включительно. Строки могут состоять только из символов с кодами от [latex]33[/latex] до [latex]126[/latex].
Результат
Для каждой операции выведите в отдельной строке сообщение в соответствии с форматом, описанным выше. Строго соблюдайте расстановку пробелов и знаков препинания в этих сообщениях.
Ограничения
- Время: 0.5 секунды
- Память: 64 МБ
Код
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
import java.io.IOException; import java.util.HashMap; import java.io.OutputStreamWriter; import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.PrintWriter; class Recode{ String pass; boolean hear; public Recode(String pass, boolean hear){ this.pass = pass; this.hear = hear; } } class Comments { public static String errNewAdd = "fail: user already exists\n"; public static String errLogin = "fail: no such user\n"; public static String errInPass = "fail: incorrect password\n"; public static String errAlIn = "fail: already logged in\n"; public static String errLogout = "fail: already logged out\n"; public static String sucNewAdd = "success: new user added\n"; public static String sucLogin = "success: user logged in\n"; public static String sucLogout = "success: user logged out\n"; } public class Main{ private static HashMap DataBase = new HashMap(); private static BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); private static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); public static void main(String[] args) throws java.lang.Exception{ int n = nextInt(); for (int i = 0; i < n; i++){ try{ Query(getRequest()); } catch(Exception e){ err(e); } } out.flush(); } public static String[] getRequest() throws IOException{ return in.readLine().split(" "); } public static void Query(String[] req){ if(req[0].equals("register")){ Registration(req[1], req[2]); } else if(req[0].equals("login")){ Login(req[1],req[2]); } else if(req[0].equals("logout")){ Logout(req[1]); } } public static void Registration(String user, String pass){ if(!DataBase.containsKey(user)){ DataBase.put(user, new Recode(pass, false)); out.print(Comments.sucNewAdd); } else{ out.print(Comments.errNewAdd); } } public static void Login(String user, String pass){ if(DataBase.containsKey(user)){ if(DataBase.get(user).pass.equals(pass)){ if(!DataBase.get(user).hear){ DataBase.put(user, new Recode(pass, true)); out.print(Comments.sucLogin); } else out.print(Comments.errAlIn); } else out.print(Comments.errInPass); } else out.print(Comments.errLogin); } public static void Logout(String user){ if(DataBase.containsKey(user)){ if(DataBase.get(user).hear){ DataBase.put(user, new Recode(DataBase.get(user).pass, false)); out.print(Comments.sucLogout); } else out.print(Comments.errLogout); } else out.print(Comments.errLogin); } public static int nextInt() throws IOException{ return Integer.parseInt(in.readLine()); } private static void err(Object a){ out.println(a); } } |
Решение
Сначала мной была создана структура в которой содержалась информация о пользователе (пароль и состояние: в сети/не в сети) и класс, в котором перечислил все комментарии, которые может выдавать программа. Далее я использовал HashMap для хранения пар вида [latex]\left\{ login => \left(password , status \right)\right\}[/latex], что позволило мне за константное время проверять указанные в задаче условия. Существование пользователя (был ли он зарегистрирован ранее) я определяю с помощью метода HashMap.containsKey(T key), что позволяет мне не заводить дополнительные структуры данных.
Описание функций
main
Главная функция программы. Считывает число запросов [latex]n[/latex], и [latex]n[/latex] раз считывает массив строк с помощью getRequest и и сразу же передает его в функцию Query, после чего программа завершает свою работу.
getRequest
Считывает строку и разбивает ее с помощью метода split по пробелу. Возвращает полученный массив.
Query
Функция — распределитель. Принимает массив строк и проверяет его первый элемент.
Если он оказался равен «register» — вызывает функцию Registration. Параметрами служат второй и третий элемент входного массива.
Если он оказался равен «login» — вызывает функцию Login. Параметрами служат второй и третий элемент входного массива.
Если он оказался равен «logout» — вызывает функцию Logout. Параметром служит второй элемент входного массива.
Request
Принимает две строки, которые определяет как логин и пароль пользователя. Проверяет несуществование пользователя. Если пользователь с таким логином не существует — добавляет запись в DataBase и печатает строку «success: new user added». Иначе — печатает соответствующую ошибку.
Login
Принимает две строки, которые определяет как логин и пароль пользователя. Проверяет существование пользователя, сверяет пароль и проверяет состояние. Если пользователь существует, пароль совпадает и статус — «не в сети» — меняем статус и печатает об успехе. Если некоторое условие не было пройдено — печатает соответствующую ошибку.
Logout
Принимает одну строку, которую определяет как логин. Проверяет существование пользователя и его статус. Если пользователь существует и статус — «в сети» — меняет статус и печатает об успехе. Иначе печатает соответствующую ошибку.
Результат проверки на acm.timus.ru
Вердикт | Время работы | Использованная Память |
Accepted | 0.078 | 548 КБ |