AcWing:第58场周赛

AcWing:第58场周赛

4488. 寻找1 - AcWing题库

给定一个长度为 n 的 01 序列 a1,a2,…,an。

请你判断,其中是否包含 1。

输入格式

第一行包含一个整数 n。

第二行包含 n 个整数 a1,a2,…,an。

输出格式

如果序列中包含 1,则输出 YES,否则输出 NO

数据范围

前三个测试点满足 1≤n≤3。
所有测试点满足 1≤n≤100,0≤ai≤1。

输入样例1:
3
0 0 1
输出样例1:
YES
输入样例2:
1
0
输出样例2:
NO

问题解析

遍历数组,找到1就输出yes结束,如果一直没输出yes,就输出no。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n'
#define int ll
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 2e5 + 50, MOD = 1e9 + 7;

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n;
    cin>>n;
    int x;
    for(int i=0;i<n;i++)
    {
        cin>>x;
        if(x==1)
        {
            cout<<"YES"<<endl;
            return 0;
        }
    }
    cout<<"NO"<<endl;
    return 0;
}

4489. 最长子序列 - AcWing题库

给定一个长度为 n 的严格单调递增的整数序列 a1,a2,…,an。

序列 a 的子序列可以表示为 ai1,ai2,…,aip,其中 1≤i1<i2<…<ip≤n。

我们希望找到一个 a 的子序列,使得该子序列满足:对于 j∈[1,p−1],aij+1≤aij×2 恒成立。

我们认为,长度为 1 的子序列总是满足条件的。

请你计算并输出满足条件的子序列的最大可能长度。

输入格式

第一行包含一个整数 n。

第二行包含 n 个整数 a1,a2,…,an。

输出格式
一个整数,表示满足条件的子序列的最大可能长度。

数据范围

前 5 个测试点满足 1≤n≤10。
所有测试点满足 1≤n≤2×105,1≤a1<a2<…<an≤109。

输入样例1:
10
1 2 5 6 7 10 21 23 24 49
输出样例1:
4
输入样例2:
5
2 10 50 110 250
输出样例2:
1

问题解析

这题乍一看,像是求最长递增子序列的nlogn做法,只是把判断条件改一下。

但是其实没有那么复杂(而且二分我也没写对),首先我们要找的序列是,当前位是前一位的两倍或更小。然后题目说了给的数组是严格递增的,那么,如果我们在找这个序列的时候,数组的当前元素大于上一位元素的两倍,那我们也不用回头去找之前的元素了,因为数组是递增的,如果靠前的元素的两倍都小于当前元素,那么比这个元素还小的靠后的元素就更不用想了。所以这题与其说是序列,不如说是子数组。

我们直接遍历数组,如果当前元素小于等于上一位元素的两倍,我们就当他是序列的最后一位元素,同时序列长度++。如果这个元素不满足,那么我们就设这个元素是序列的开头,把序列长度恢复成1。在此过程中维护一下序列最大值即可。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n'
#define int ll
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 2e5 + 50, MOD = 1e9 + 7;

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n;
    cin >> n;
    vector<int>v(n), f(n + 2,0);
    for (int i = 0; i < n; i++)
    {
        cin >> v[i];
    }
    int res = 0,ans=0;
    for (int i = 0; i < n; i++)
    {
        if (f[ans] * 2 >= v[i])
        {
            f[ans + 1] = v[i];
            res = max(res, ++ans);
        }
        else
        {
            f[1] = v[i];
            ans = 1;
            res = max(res, ans);
        }

    }
    cout << res << endl;
    return 0;
}

4490. 染色 - AcWing题库

给定一个 n 个节点的树,节点编号为 1∼n。

1 号节点是树的根节点。

初始时,所有节点的颜色均为 0。

现在,你需要对该树进行重新染色,其中节点 i 的目标颜色为 ci。

每次染色操作的具体流程如下:

选择一个节点 v 和一种颜色 x。
将以节点 v 为根节点的子树中的全部节点(包括节点 v)都染成颜色 x。
请你计算,为了使得每个节点都被染成目标颜色,至少需要进行多少次染色操作。

输入格式

第一行包含整数 n。

第二行包含 n−1 个整数 p2,p3,…,pn,其中 pi 表示节点 i 的父节点编号。

第三行包含 n 个整数 c1,c2,…,cn,其中 ci 表示节点 i 的目标颜色。

保证输入给定图是一棵树。

输出格式

一个整数,表示最少所需的染色操作次数。

数据范围

前三个测试点满足 2≤n≤10。
所有测试点满足 2≤n≤10^ 4,1≤pi<i,1≤ci≤n。

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

问题解析

首先我们先想一下染色的情况,因为我们染色是一次性把一个根节点和这个节点的子树给染成同一种颜色。那么如果子树的颜色和根节点不同,那么肯定是先染了根节点,再去染子树。所以我们染色的步骤是从根节点开始,逐步染色的。

那么我们可以dfs来处理,如果这个节点当前的颜色和目标颜色不同,我们就要把这一整个子树都染成它的目标颜色,染色次数++,然后遍历它的所有孩子,并且把这个节点的目标颜色当初他们孩子新的颜色。然后当孩子目标颜色和这个颜色不同时,就继续染色。

最后输出染色次数即可。

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>

#define endl '\n'
#define int ll
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 2e5 + 50, MOD = 1e9 + 7;
unordered_map<int, int>color;
unordered_map<int, vector<int>>mymap;

int cnt = 0;
//x是当前节点的值,y是这个节点的父节点的颜色
void dfs(int x,int y)
{
    if (y != color[x])cnt++;
    for (auto i : mymap[x])
    {
        dfs(i, color[x]);
    }
}

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n, x;
    cin >> n;
    for (int i = 2; i <= n; i++)
    {
        cin >> x;
        mymap[x].push_back(i);
    }
    for (int i = 1; i <= n; i++)
    {
        cin >> x;
        color[i] = x;
    }
    dfs(1,0);
    cout << cnt << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值