Codeforces: Round #704 (Div.2)
Codeforces
A. Three swimmers
Three swimmers decided to organize a party in the swimming pool! At noon, they started to swim from the left side of the pool.
It takes the first swimmer exactly 𝑎 minutes to swim across the entire pool and come back, exactly 𝑏 minutes for the second swimmer and 𝑐 minutes for the third. Hence, the first swimmer will be on the left side of the pool after 0,𝑎,2𝑎,3𝑎,… minutes after the start time, the second one will be at 0,𝑏,2𝑏,3𝑏,… minutes, and the third one will be on the left side of the pool after 0,𝑐,2𝑐,3𝑐,… minutes.
You came to the left side of the pool exactly 𝑝 minutes after they started swimming. Determine how long you have to wait before one of the swimmers arrives at the left side of the pool.
Input
The first line of the input contains a single integer 𝑡 (1≤𝑡≤1000) — the number of test cases. Next 𝑡 lines contains test case descriptions, one per line.
Each line contains four integers 𝑝,𝑎,𝑏 and 𝑐 (1≤𝑝,𝑎,𝑏,𝑐≤1018), time in minutes after the start, when you came to the pool and times in minutes it take the swimmers to cross the entire pool and come back.
Output
For each test case, output one integer — how long you have to wait (in minutes) before one of the swimmers arrives at the left side of the pool.
풀이
p보다 큰 a, b, c 의 배수를 구한 뒤 p를 뺀 값 중 가장 작은 값을 출력한다.
코드
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll abc[3];
void solve() {
ll p; cin >> p;
for (int i = 0; i < 3; i++) {
cin >> abc[i];
}
ll ans = LLONG_MAX;
for (int i = 0; i < 3; i++) {
ll tmp = abc[i] * ((p + abc[i] - 1) / abc[i]);
ans = min(ans, tmp - p);
}
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t; cin >> t;
while(t--) solve();
return 0;
}
B. Card Deck
You have a deck of 𝑛 cards, and you’d like to reorder it to a new one.
Each card has a value between 1 and 𝑛 equal to 𝑝𝑖. All 𝑝𝑖 are pairwise distinct. Cards in a deck are numbered from bottom to top, i. e. 𝑝1 stands for the bottom card, 𝑝𝑛 is the top card.
In each step you pick some integer 𝑘>0, take the top 𝑘 cards from the original deck and place them, in the order they are now, on top of the new deck. You perform this operation until the original deck is empty. (Refer to the notes section for the better understanding.)
Let’s define an order of a deck as ∑𝑛𝑖=1𝑛𝑛−𝑖⋅𝑝𝑖.
Given the original deck, output the deck with maximum possible order you can make using the operation above.
Input
The first line contains a single integer 𝑡 (1≤𝑡≤1000) — the number of test cases.
The first line of each test case contains the single integer 𝑛 (1≤𝑛≤105) — the size of deck you have.
The second line contains 𝑛 integers 𝑝1,𝑝2,…,𝑝𝑛 (1≤𝑝𝑖≤𝑛;𝑝𝑖≠𝑝𝑗 if 𝑖≠𝑗) — values of card in the deck from bottom to top.
It’s guaranteed that the sum of 𝑛 over all test cases doesn’t exceed 105.
Output
For each test case print the deck with maximum possible order. Print values of cards in the deck from bottom to top.
If there are multiple answers, print any of them.
풀이
최댓값을 구하는 방법을 몰라 TLE가 떴던 문제이다.
p를 카드 중 가장 큰 값 n 부터 가장 작은 값 1 까지 줄여나가면서 p의 인덱스가 잘라낸 카드에 속해 있으면 p의 값을 하나씩 줄인다.
속하지 않는다면 p의 위치에서부터 잘라내기 전 카드까지 출력하고 p의 위치를 l로 정의하여 p의 위치 이후를 잘라낸다.
코드
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int A[101010];
int pos[101010];
void solve() {
int n; cin >> n;
for (int i = 1; i <= n; i++) {
cin >> A[i];
pos[A[i]] = i;
}
int p = n, l = n + 1;
while (p >= 1) {
if (pos[p] >= l) { p--; continue; }
for (int i = pos[p]; i < l; i++) cout << A[i] << " ";
l = pos[p];
}
cout << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t; cin >> t;
while(t--) solve();
return 0;
}