Atcoder ARC 095

C Many Medians

source

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时停止。

posted @ 2018-04-27 11:08  hxidkd  阅读(354)  评论(0编辑  收藏  举报