• CodeForces 1375D. Replace by MEX


    题意:你被给予了一个数组,包含n个[0, n]的整数。每一次操作,你可以选择数组中的一个元素替换成这个数组的MEX。例如,如果数组是[0, 2, 2, 1, 4],你可以选择第二个元素替换成整个数组元素的MEX,数组会变成[0, 3, 2, 1, 4]。(MEX的定义为不包含这个于这个数组的最小的非负整数。)

    分析:首先,题目给出操作的次数最多为2n次,这是不是暗示我们先把数组通过n次变成一个样子,再通过n次变成另一个样子?我们把ai( eq)i称之为一个未修复点,我们可以进行如下的操作来修复每一个点。
    1.如果mex = n,我们就任意地替换一个未修复点。
    2.如果mex < n,我们就替换下标是mex的点。
    这两个操作最多2n次,每一次操作可以使得未修复的点减少一次。为什么这么做呢?因为每次如果求出一个mex = n的时候,就可以使得下一次修复的时候,mex < n。我们的目的就是为了修复一个点的时候,让mex < n,这样可以正常的修复。(求mex是线性的。)

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <map>
    #include <algorithm>
    
    using namespace std;
    const int N = 1005;
    int a[N];
    map<int, int> mp;
    
    int mex()
    {
    	for (int i = 0; ; ++i)
    	{
    		if (mp.find(i) == mp.end())
    		{
    			return i;
    		}
    	}
    }
    
    int main()
    {
    	int t;
    	scanf("%d", &t);
    
    	while (t--)
    	{
    		int n;
    		scanf("%d", &n);
    
    		for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
    
    		bool flag = true;
    		for (int i = 0; i < n - 1; ++i)
    		{
    			if (a[i] > a[i + 1])
    			{
    				flag = false;
    				break;
    			}
    		}
    		if (!flag)
    		{
    			vector<int> res;
    			for (int i = 0; i < n; ++i)
    			{
    				++mp[a[i]];
    			}
    			while (1)
    			{
    				bool flag = true;
    				for (int i = 0; i < n - 1; ++i)
    				{
    					if (a[i] > a[i + 1])
    					{
    						flag = false;
    						break;
    					}
    				}
    				if (flag)
    				{
    					break;
    				}
    				int t = mex();
    				int old;
    				if (t == n)
    				{
    					int i;
    					for (i = 0; i < n; ++i)
    					{
    						if (a[i] != i)
    						{
    							old = a[i];
    							a[i] = t;
    							res.push_back(i + 1);
    							break;
    						}
    					}
    					//pos---位置
    					--mp[old];
    					if (mp[old] == 0)
    					{
    						mp.erase(old);
    					}
    					++mp[a[i]];
    				}
    				else if (t < n)
    				{
    					//int t = mex();
    					int old = a[t];
    					a[t] = t;
    					res.push_back(t + 1);
    
    					--mp[old];
    					if (mp[old] == 0)
    					{
    						mp.erase(old);
    					}
    					++mp[a[t]];
    				}
    			}
    			printf("%d
    ", res.size());
    			for (int i = 0; i < res.size(); ++i)
    				printf("%d ", res[i]);
    		}
    		else
    		{
    			puts("0");
    
    		}		
    
    		puts("");
    		mp.clear();
    	}
    	
    
    	return 0;
    }
    
  • 相关阅读:
    8.1.2 绑定Activity和Service
    8.1.1 Service的生命周期
    接收广播BroadcastReceiver
    Android Activity和Intent机制学习笔记
    Android开发笔记之:Handler Runnable与Thread的区别详解
    Android工程:引用另一个Android工程的方法详解
    android之内容提供者解析
    Android应用程序组件Content Provider的共享数据更新通知机制分析
    Red5实现直播
    轻松学习 red5 教程 像视频一样很详细还有代码直接可Copy
  • 原文地址:https://www.cnblogs.com/pixel-Teee/p/13238172.html
Copyright © 2020-2023  润新知