Acwing63周赛+Leetcode305周赛

Acwing63周赛+Leetcode305周赛

ACW

link题目链接


0≤x≤a
0≤y≤b
x+y=n
例如,当 a=5,b=6,n=3 时,共有 4 个满足条件的数对:(0,3),(1,2),(2,1),(3,0)。

输入格式
第一行包含整数 a。

第二行包含整数 b。

第三行包含整数 n。

输出格式
一个整数,表示满足条件的数对数量。

数据范围
前三个测试点满足 1≤a,b≤10,1≤n≤a+b。
所有测试点满足 1≤a,b≤300,1≤n≤a+b。

输入样例1:
5
6
3
输出样例1:
4
输入样例2:
5
3
5
输出样例2:
4

对于此题,显然可以使用双指针对其进行遍历求解,这里不再赘述
对此我提供我自己的一个思路,复杂度为常数

对于给定的a,b,n仔细观察即可发现其实对于所求res有直接的影响关系,如下
if(a >= n && b>=n) res = n+1;
else if(a>=n && b < n) res = b+1;
else if(b>=n && a < n) res = a+1;
对此可直接实现,实测是最快解


游戏规则如下:

给定一个由小写字母构成的字符串 s。
两人轮流进行消除操作,当轮到一人时,其任务是在当前 s 中找到两个连续且相同的字母,并将它们从 s 中消除。例如,当 s 为 abba 时,可以消除 bb,使 s 变为 aa。
第一个无法进行消除操作的选手视为失败。
已知,游戏由李华执先手,且两人都采取最优策略。

请问,李华是否可以获胜。

输入格式
一行,一个字符串 s。

输出格式
如果李华可以获胜,则输出 Yes,否则输出 No。

数据范围
前 5 个测试点满足 1≤|s|≤10。
所有测试点满足 1≤|s|≤105。

输入样例1:
abacaba
输出样例1:
No
输入样例2:
iiq
输出样例2:
Yes
输入样例3:
abba
输出样例3:
No

对于此题,我们需要证明对于所有的相同数块消除的先手顺序没有影响,这里我个人认为比较显然,链接中有详细的数学归纳法证明方式,可以参考。
有了以上结论,可得我们需要一个stack来维护s,对其情况分析即可
代码如下,可供参考


using namespace std;
const int N = 100010;
int n;
int m;
int a, b;
string s;
int res = 0;
int main() {
    cin >> s;
    stack<char> st;
    for ( auto c : s){
        if(st.empty()) st.push(c);
        else if(c == st.top()){
            st.pop();
            res ++;
        } else {
            st.push(c);
        }
    }
    if(res % 2 == 0) cout << "No" ;
    else cout << "Yes";
}

集合中的元素两两不同。

请你找到一个该集合的最大子集,要求子集内的元素满足任意两元素之差的绝对值都是 2 的整数幂。

注意,只包含 1 个元素的子集一定满足条件。

输入格式
第一行包含整数 n。

第二行包含 n 个两两不同的整数 x1,x2,…,xn。

输出格式
第一行输出一个整数 m,表示满足条件的最大子集包含的元素数量。

第二行包含 m 个整数,表示最大子集中包含的元素。

如果方案不唯一,则输出任意合理方案均可。

数据范围
前 6 个测试点满足 1≤n≤10。
所有测试点满足 1≤n≤2×105,−109≤xi≤109。

注意:本题数据范围较大,慎用cin/cout、unordered_set、unordered_map等操作。

输入样例1:
6
3 5 4 7 10 12
输出样例1:
3
7 3 5
输入样例2:
5
-1 2 5 8 11
输出样例2:
1
8

对于此题需要更严谨的证明方式,我这里提供一个思路:
首先我们需要知道,所求解最多只有三个数,对此我们不妨设有四个,对其我们可以得到一个等式,对于等式可以利用数论中奇偶判别法证明不成立,对此假设无效,对此可得最多有三个数,这样我们可以直接遍历数组,寻找所求解

设有三个数A,B,C设有三个数A,B,C
满足A<B<C满足A<B<C
若A+2x=B若A+2x=B
B+2y=CB+2y=C
A+2z=CA+2z=C
那么A+2x+2y=C那么A+2x+2y=C
即2x+2y=2z即2x+2y=2z
满足x=y,z=x+1满足x=y,z=x+1
B=A+2xB=A+2x
C=B+2xC=B+2x
C=A+2x+1C=A+2x+1
设有四个数A,B,C,D设有四个数A,B,C,D
A<B<C<DA<B<C<D
若能成立,一定满足:若能成立,一定满足:
B=A+2x
B=A+2x
C=B+2x
C=B+2x
C=A+2x+1
C=A+2x+1
D=A+2x+2
D=A+2x+2
D=C+2x+1
D=C+2x+1
又因为又因为
D=C+2x+1=B+2x+2x+1
D=C+2x+1=B+2x+2x+1
不满足性质,即取出的数最多只能有3个不满足性质,即取出的数最多只能有3个

代码如下:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 200010, C = 32, M = 19999997, inf = 0x3f3f3f3f;

int h[M];
int g[N][C], a[N];

int find(int x) // 手写hash
{
    int t = (x % M + M) % M;
    while (h[t] != inf && h[t] != x)
        if (++ t == M)
            t = 0;
    return t;        
}

int main()
{
    memset(h, 0x3f, sizeof h);

    int n;
    scanf("%d", &n);

    for (int i = 1; i <= n; i ++ )
    {
        scanf("%d", &a[i]);
        h[find(a[i])] = a[i];
    }

    sort(a + 1, a + n + 1);

    for (int i = 1; i <= n; i ++ )
        for (int j = 0; j < C; j ++ )
        {
            ll k = (ll)a[i] + (1 << j);
            if (k > 1e9)continue;
            if (h[find(k)] == inf)continue;
            g[i][j] = 1;
        }

    int res = 1, ii, jj;
    for (int i = 0; i < C - 1; i ++ )//枚举x
    {
        for (int j = 1; j <= n; j ++ )
        {
            int m = g[j][i] + g[j][i + 1] + 1;
            if (m > res)
            {
                res = m;
                ii = i, jj = j;
            }
            if (res == 3)break;
        }
        if (res == 3)break;
    }

    printf("%d\n", res);
    if (res == 1)cout << a[1];
    else
    {
        printf("%d ", a[jj]);
        if (g[jj][ii])printf("%d ", a[jj] + (1 << ii));
        if (g[jj][ii + 1])printf("%d ", a[jj] + (1 << ii + 1));
    }

    return 0;
}

Leetcode

在这里插入图片描述1
3
第四题未解决
第二题卡了一个样例tle,但是我自己的代码显然比过了的dfs快,线性复杂度
在这里插入图片描述

这里就是acwing和leetcode的所有题目的个人解法,望指正

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值