10.3题解

考场脑抽T2读错题了

T1

签到题。

模拟大家都会,下面是 $O(1)$ 做法:

#include <iostream>
using namespace std;
int w, k, a, n;
int main()
{
    cin >> w >> k >> a >> n;
    if(n > k)
        cout << (2 * n * w + a * k * (2 * n - k - 1)) / 2;
    else
        cout << n * (2 * w + a * (n - 1)) / 2;
    return 0;
}

T2

下图中特别大的两个点是对称点,没有箭头的点坐标为 (x,y)。

主对角线:

副对角线:

注意判断点是否喵喵点时,既要判断本身,又要判断对称点!

如果某个位置是 1 ,并且它关于主对角线对称的位置和关于副对角线对称的位置都为 1 ,那么这个点就称为一个喵喵点。

#include <iostream>
#include <cstdio>
using namespace std;
int n, a[150][150], ans, vx, vy;
int main()
{
    cin >> n;
    for(int i = 1;i <= n;++i)
        for(int j = 1;j <= n;++j)
            scanf("%1d", &a[i][j]);
    for(int i = 1;i <= n;++i)
        for(int j = 1;j <= n;++j)
            if(a[i][j] && a[j][i] && a[n - j + 1][n - i + 1]) ++ans;
    cout << ans;
    return 0;
}

T3

我们要知道,选出的两个数排序后一定相邻。


首先,$(a\wedge b)\oplus(a\vee b)$ 与 $a\oplus b$ 是等价的。

因为 $a\wedge b$ 算的是 $a,b$ 二进制中的交,

$a\vee b$ 算的是 $a,b$ 二进制中的并,

而且并一定是包含交的,

而交和并的不同部分,就是在并中但不在交中的部分,

换句话说,就是 $a,b$ 中的不同部分,也就是 $a\oplus b$。

那么题意就可以转化为:

给定数列 $a$,选出两个数 $a_x,a_y$,使得 $a_x\oplus a_y$ 最小。


那么为什么选出的两个数排序后一定相邻呢?

我们知道,想要两个数异或值最小,那么这两个数要尽量接近。

那么我们假如选了排序后不相邻的 $a_x,a_y$,

则排序后的 $a_{x+1}\oplus a_y$ 和 $a_x\oplus a_{y-1}$ 一定有一个 $<$ $a_x\oplus a_y$。

所以只需要拍一遍序,枚举相邻的两个数,每次更新答案即可。

#include <iostream>
#include <algorithm>
using namespace std;
int n, a[100050], ans = 1e9;
int main()
{
    cin >> n;
    for(int i = 0;i < n;++i)
        cin >> a[i];
    sort(a, a + n);
    for(int i = 1;i < n;++i)
        ans = min(ans, a[i] ^ a[i - 1]);
    cout << ans;
    return 0;
}

T4

$To\ Be\ Continue$

posted @ 2021-10-04 09:39  Jijidawang  阅读(5)  评论(0编辑  收藏  举报  来源