• Ehab and Prefix MEXs(STL, 思维,模拟)


    Ehab and Prefix MEXs

    原题链接:传送门

    题目大意

    给定一个数组a,长度为n,要求你找到一个数组b满足:

    对于每一个 (a_i = MEX({b_1 , b_2,...b_n})),

    MEX 运算表示不在集合中的最小的非负整数。

    分析

    做的时候突然没有思路,现在理一下思路和做法。

    首先先观察找规律,如果要在b[i] 上放一个元素,那么这个元素一定不在a[i]~a[n]中出现过,否则在后面就会产生矛盾。

    那么我们可以用一个set集合,将所有从i位置以后(包括i)没有在a中出现过的数字存下来。每一次必然从这个set中取出一个数字存入数组b中再将这个数从set中删除。

    我们来推里一下这个方法为什么是正确的:

    首先如果对于 a[i-1] 成立的话,对于a[i],0~a[i]-1中一定已经被填满了,因为a[i] <= i,前面填了 i - 1 个数子,b又是按照从小到大的顺序存储的,所以只要b取a[i-1]即可满足条件。

    如果a[i] == a[i-1] 时,那么继续取set中的第一个数即可。

    实际上对于该问题:a[i] <= i 就解决了不可能没有解的情况

    注意事项

    认真分析,div2 C题一般都是STL的用法和一些基础的贪心dp冷静思考耐心观察一般都可以做出来的 加油

    AC 代码

    AC code

    void slove()
    {
    	int n;cin >> n;
    	vector<int> a(n);
    	map<int,int> m;
    	set<int> b;
    	for(int i = 0;i < n ;i ++)
    	{
    		cin >> a[i];m[a[i]] = 1; 
    	}
    	for(int i = 0;i <= 2 * n;i ++)
    	{
    		if(m[i] == 0)b.insert(i);
    	}
    	for(int i = 0;i < n ;i ++)
    	{
    		if(i && a[i] != a[i-1])b.insert(a[i-1]);
    		cout << *b.begin() << " ";
    		b.erase(*b.begin());
    	}
    }
    

    标程/优秀代码

    #include <bits/stdc++.h>
    using namespace std;
    int a[100005],b[100005];
    bool ex[100005];
    int main()
    {
    	int n;
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++)
    	scanf("%d",&a[i]);
    	memset(b,-1,sizeof(b));
    	for (int i=1;i<=n;i++)
    	{
    		if (a[i]!=a[i-1])
    		{
    			b[i]=a[i-1];
    			ex[b[i]]=1;
    		}
    	}
    	ex[a[n]]=1;
    	int m=0;
    	for (int i=1;i<=n;i++)
    	{
    		while (ex[m])
    		m++;
    		if (b[i]==-1)
    		{
    			b[i]=m;
    			ex[m]=1;
    		}
    		printf("%d ",b[i]);
    	}
    }
    
  • 相关阅读:
    监视用户是保存用户编辑还是放弃参照编辑
    AutoCAD: 添加鼠标快捷键/鼠标右键
    C# List<T>集合布尔运算
    List<T>的用法详解
    天正的坑
    C#札记
    AUTOCAD2013 以上利用ACCORECONSOLE+ SCR后台批量清理图纸
    BaiduSitemap
    三一邮件群发
    Windows+IIS+Mysql+php安装
  • 原文地址:https://www.cnblogs.com/wlw-x/p/13692321.html
Copyright © 2020-2023  润新知