Atcoder ARC 095
C Many Medians
Time limit : 2sec / Memory limit : 256MB
Problem Statement
When l is an odd number, the median of l numbers a1,a2,…,al is the ( l+1 2 )-th largest value among a1,a2,…,al.
You are given N numbers X1,X2,…,XN, where N is an even number. For each i=1,2,…,N, let the median of X1,X2,…,XN excluding Xi, that is, the median of X1,X2,…,Xi−1,Xi+1,…,XN be Bi.
Find Bi for each i=1,2,…,N.
Constraints
2≤N≤200000
N is even.
1≤Xi≤109
All values in input are integers.
Input
Input is given from Standard Input in the following format:
N
X1 X2 ... XN
Output
Print N lines. The i-th line should contain Bi.
Sample Input 1
4
2 4 4 3
Sample Output 1
4
3
3
4
Since the median of X2,X3,X4 is 4, B1=4.
Since the median of X1,X3,X4 is 3, B2=3.
Since the median of X1,X2,X4 is 3, B3=3.
Since the median of X1,X2,X3 is 4, B4=4.
Sample Input 2
2
1 2
Sample Output 2
2
1
Sample Input 3
6
5 5 4 4 3 3
Sample Output 3
4
4
4
4
4
4
题意
给一个数组,求去掉当前元素之后数组的中位数, 数的个数保证为偶数。
题解
显然结果肯定是排序后N/2,(N-1)/2中取一个,当前元素大于N/2时则取(N-1)/2,反之亦然。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
int n;
cin >> n;
vector<int> nums(n);
vector<int> cp(n);
for (int i = 0; i < n; i++) {
cin >> nums[i];
cp[i] = nums[i];
}
sort(nums.begin(), nums.end());
int index = n / 2;
for (int i = 0; i < n; i++) {
if (cp[i] < nums[index]) {
cout << nums[index];
} else {
cout << nums[index-1];
}
cout <<"\n";
}
return 0;
}
D - Binomial Coefficients
Problem Statement
Let comb(n,r) be the number of ways to choose r objects from among n objects, disregarding order. From n non-negative integers a1,a2,…,an, select two numbers ai>aj so that comb(ai,aj) is maximized. If there are multiple pairs that maximize the value, any of them is accepted.
Constraints
2≤n≤105
0≤ai≤109
a1,a2,…,an are pairwise distinct.
All values in input are integers.
Input
Input is given from Standard Input in the following format:
n
a1 a2 … an
Output
Print ai and aj that you selected, with a space in between.
Sample Input 1
5
6 9 4 2 11
Sample Output 1
11 6
comb(ai,aj) for each possible selection is as follows:
comb(4,2)=6
comb(6,2)=15
comb(6,4)=15
comb(9,2)=36
comb(9,4)=126
comb(9,6)=84
comb(11,2)=55
comb(11,4)=330
comb(11,6)=462
comb(11,9)=55
Thus, we should print 11 and 6.
Sample Input 2
2
100 0
Sample Output 2
100 0
题意
从数组中取两个数n, m,使得\(C_{n}^{m}\)最大 。
题解
显然对相同的m,底数n越大越好,贪心取最大的即可。之后取m的话应该尽量靠近n/2(可通过不同的m比值来证明)。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
int n;
cin >> n;
vector<int> nums(n);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
sort(nums.begin(), nums.end());
cout << nums.back() << " ";
int mn = nums[0];
double mid = nums.back() / 2.0;
for (int i = 1; i < n; i++) {
if (abs(1.0 * mn - mid) > abs(1.0*nums[i]-mid)) {
mn = nums[i];
}
}
cout << mn << "\n";
return 0;
}
E - Symmetric Grid
Time limit : 2sec / Memory limit : 256MB
Problem Statement
There is an H×W grid (H vertical, W horizontal), where each square contains a lowercase English letter. Specifically, the letter in the square at the i-th row and j-th column is equal to the j-th character in the string Si.
Snuke can apply the following operation to this grid any number of times:
Choose two different rows and swap them. Or, choose two different columns and swap them.
Snuke wants this grid to be symmetric. That is, for any 1≤i≤H and 1≤j≤W, the letter in the square at the i-th row and j-th column and the letter in the square at the (H+1−i)-th row and (W+1−j)-th column should be equal.
Determine if Snuke can achieve this objective.
Constraints
1≤H≤12
1≤W≤12
|Si|=W
Si consists of lowercase English letters.
Input
Input is given from Standard Input in the following format:
H W
S1
S2
:
SH
Output
If Snuke can make the grid symmetric, print YES; if he cannot, print NO.
Sample Input 1
2 3
arc
rac
Sample Output 1
YES
If the second and third columns from the left are swapped, the grid becomes symmetric.
Sample Input 2
3 7
atcoder
regular
contest
Sample Output 2
NO
Sample Input 3
12 12
bimonigaloaf
faurwlkbleht
dexwimqxzxbb
lxdgyoifcxid
ydxiliocfdgx
nfoabgilamoi
ibxbdqmzxxwe
pqirylfrcrnf
wtehfkllbura
yfrnpflcrirq
wvcclwgiubrk
lkbrwgwuiccv
Sample Output 3
YES
题意
H×W矩阵,任意选择两行或两列进行交换,可换多次,求最后能否使得矩阵对称。也就是第i行和h-1-i行回文,列同理。
题解
扎心,不知道为什么,看到这种题就晃。明明暴力枚举就行。
首先,行和列的交换是独立的,可认为先交换完行,再交换列。先枚举行的交换,由于只需要对应的行组成pair即可,不需要考虑相对顺序。也就是可以固定第一行,然后从11个里面选一行当第12行。再固定第二行,从9个里面选一行当第11行,以此类推。总的枚举次数为11×9×7... = 11!!
其次,再固定行之后怎么判断能不能通过列交换达对称呢。因为此时没有行交换了,所以每一列内的元素是固定的,所以枚举每一列有没有对应的列是他的回文就行。复杂度O(HWW)
#include<bits/stdc++.h>
using namespace std;
int h, w;
vector<string> s;
int used[20];
bool ans = false;
int cnt = 0;
bool equals(int x, int y) {
for (int i = 0; i < h; i++) {
if (s[i][x] != s[h-1-i][y]) return false;
}
return true;
}
bool check() {
memset(used, 0, sizeof(used));
bool f = false;
for (int i = 0; i < w; i++) {
if (used[i]) continue;
bool ok = false;
for (int j = i+1; j < w; j++) {
if (used[j]) continue;
if (equals(i, j)) {
ok = true;
used[j] = 1;
break;
}
}
if (!ok) {
if (w % 2 == 0 || f) return false;
f = true;
}
}
return true;
}
void dfs(int cur, bool odd) {
if (cur >= (h-1) / 2) {
//cout << "\n";
//for (string &str : s) cout << str << "\n";
ans |= check();
return;
}
if (odd) {
swap(s[cur], s[h/2]);
for (int j = cur + 1; j < h - cur; j++) {
swap(s[j], s[h-1-cur]);
dfs(cur+1, odd);
swap(s[j], s[h-1-cur]);
}
swap(s[cur], s[h/2]);
}
for (int j = cur + 1; j < h - cur; j++) {
swap(s[j], s[h-1-cur]);
dfs(cur+1, odd);
swap(s[j], s[h-1-cur]);
}
}
int main() {
cin >> h >> w;
s.resize(h);
for (int i = 0; i < h; i++) {
cin >> s[i];
}
dfs(0, h % 2 == 1);
if (ans) cout << "YES\n";
else cout << "NO\n";
return 0;
}
第一次wa点: 1 check中出错,ok变量乱七八糟,独立出equals清晰流程。
2 枚举时到(h-1) / 2时停止。