이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
/*
Ideas + Goals
- Find out how many unique costumes there are and store them
- Then, look through all of the custumes (that are repeated (so not detected in our first search of unique cpstumes))
- Use binary search (divide and conquer) the list of unique costumes to narrow down on WHICH costomes I repeated with
Implmention details
- To find out how many unique customes, we can't only check pairs of people. What if we just start from the beginning, and expand our window by adding more
people into our query. This keeps the previous results (total number of repeats/uniques we have seen), and checks it against the newly added element.
Unlike checking pairs, we don't know whether we have seem that costume before, so we can't determine if it is a repeat globally, we can only determine if it
repeats with that pair. We start from the beginning because we only really care about the first time a costume shows up, as that tells us the totla number
of unique customes, and we will store that in a set call "all".
- To check the reamining costumes (the ones not deems as the first of a unique costume), we will need to use binary search. Do binary search on the list we created
called "all", which has all of the unique costumes. We divide the list into halves everytime, and checks the current element against it. Since we know all the
elems in the set are unique, if plus the additional element, the query gives a size of mid+1, we know that the current element DOES NOT repeat with any of the
elems in that half. So it must repeat in the other half, so we increament/decrament high/low accordingly.
*/
vector<int> all;
int main(){
int n;
cin >> n;
int ans[n];
memset(ans, 0, n*sizeof(ans[0]));
int g = 1;
int prev = 0;
for (int i=1; i<=n; i++){
// Pass through all the elements by adding new element into our query, to check if it has appeard before (if not, it is new, add into the "all" list)
cout << i << " ";
for (int j=1; j<=i; j++){
cout << j << " ";
}
cout << "\n";
fflush(stdin);
int res = 0;
cin >> res;
if (res > prev){
// This element is new, as we have an additional costume compared to before
all.push_back(i);
ans[i-1] = g++;
}
prev = res;
}
// We have filled in our ans[] for all the FIRST appearences of costumes. The onces left are repeats, so we need to determine which costume it repeats with
for (int i=1; i<=n; i++){
if (ans[i-1] == 0){
// Do binary search to divide and conquer the "all" list
int low = 0; int high = all.size()-1;
while (low < high){
int mid = (low + high)/2;
cout << (mid-low+1)+1; // Mid is 0 base indexed, so mid+1 for number of elements in the "all" list, and +1 for our current element. Totoal m+2 elems printed
for (int j=low; j<=mid; j++){
cout << " " << all[j];
}
cout << " " << i << "\n";
fflush(stdin);
int res = 0;
cin >> res;
if (res == mid+2){
// Current element does not repeat with any elements in this section of the list (low to mid)
low = mid+1;
}else{
// Low to mid does contain a repeat of the current element
high = mid;
}
}
// Now we should have low = index of the repeated element in th all[]
ans[i-1] = ans[all[low]-1]; // Then since I am repeated with all[low] my ans = ans[all[low]]
}
}
cout << "0 ";
for (int i : ans){
cout << i << " ";
}
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |