Codeforces Global Round 9 (A——D)

题目地址

一、Sign Flipping

题意:给你一个大小为n的数组(n为奇数),现在你可以改变其中元素的符号,要求你在操作后,使得有至少一半的ai <= ai+1,同时至少有一半ai >= ai+1,构造出这个数组

思路:只要一直正负正负下去,一定成立。

#include
#include
#include
#include
using namespace std;
long long a[10001];
int n, m;
int main()
{
	cin >> n;
	while (n--)
	{
		cin >> m;
		for (int i = 1; i <= m; i++)
		{
			cin >> a[i];
		}
		for (int i = 1; i <= m; i++)
		{
			if (i % 2 == 1)
				cout << abs(a[i]) << " ";
			else
				cout << -abs(a[i]) << " ";
		}
		cout << endl;
	}

}

B. Neighbor Grid

题意:给你一个二维数组,现在要求二维数组中的每一个位置的元素值的多少都要对应于周围有多少个相邻的不为0的数的个数。现在你每次可以对二维数组的元素加一,问是否能构造出这样的二维数组。

思路:这个正常做比较难想,何不把矩阵变满,比如四阶,三阶:
2 3 3 2
3 4 4 3
3 4 4 3
2 3 3 2
三阶:
2 3 2
3 4 3
2 3 4
发现规律:四个角为2,边为3,里面为4;如果一超过的必定不成立。

#include
#include
using namespace std;
long long a[305][305];
int n, m,t;
int main()
{
	cin >> t;
	while (t--)
	{
		int flag = 1;
		cin >> n >> m;
		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= m; j++)
			{
				cin >> a[i][j];
				if ((i == 1 && j == 1) || (i == 1 && j == m) || (i == n && j == 1) || (i == n && j == m))
				{//四角
					if (a[i][j] > 2)
					flag = 0;
				}
				if (i == 1 || j == 1 || i == n || j == m)
				{//四边
					if (a[i][j] > 3)
						flag = 0;
				}
				if (a[i][j] > 4)
					flag = 0;
			}
		}
		if (flag)
		{
			cout << "YES" << endl;
			for (int i = 1; i <= n; i++)
			{
				for (int j = 1; j <= m; j++)
				{
					if ((i == 1 && j == 1) || (i == 1 && j == m) || (i == n && j == 1) || (i == n && j == m)) 
					cout << 2 << " ";
					else if (i == 1 || j == 1 || i == n || j == m) 
					cout << 3 << " ";
					else cout << 4 << " ";
				}
				cout << endl;
			}
		}
		else
			cout << "NO" << endl;
		cout << endl;
	}
}

C.Element Extermination

大意:给你n大小的数组排列,现在如果有俩个连续的数满足ai < ai+1,那么你可以删去其中的一个数,现在问:在进行上述操作后,是否有可能使得数组中元素的个数为1

思路:用栈操作,如果此时栈为空,入栈。如果此时栈中有元素,且现在输入的元素小于栈顶元素,那么执行不了删除操作,把现在输入的元素入栈。如果满足删除条件,那就有两种情况。第一种,栈中只有一个元素,那么我们删掉入栈的元素,因为要留下小的给以后的元素。第二种,栈中有多于一个的元素,那代表现在栈顶元素较小,应该删除较小的元素保留大的,使其尽可能的去和栈中的其他元素匹配删除。

#include
#include
#include
#include
using namespace std;
int n, m,t;
int main()
{
	cin >> t;
	while (t--)
	{
		cin >> n;
		stack < int > s;
		while (n--)
		{
			cin >> m;
			if (s.empty())
				s.push(m);
			else if (s.top() < m)
			{//删除
				if (s.size() == 1)
					//只有一个,该元素不入栈,重新开始循环
					continue;
				else
					s.push(m);
				while (1)//循环删除栈中符合的元素
				{
					int x = s.top(); s.pop();
					int y = s.top(); s.pop();
					if (x > y)
					{
						if (s.empty())
							//栈中没有元素,就要留下小的以匹配后面的
							s.push(y);
						else
							//没有的话就要保留大的元素以匹配后面的
							s.push(x);
					}
					else
					{//注意先后顺序
						s.push(y); s.push(x);
						break;
					}
					if (s.size() == 1)break;
				}
			}
			else
				s.push(m);
		}
		if (s.size() == 1) cout << "YES" << endl;
		else cout << "NO" << endl;
	}
}

D. Replace by MEX

大意:给你一个有n个元素的数组a(n<=1000),最多进行2*n次操作,使得这个数组为非严格单调上升数组。操作定义为任意选定一个元素,使其变成mex。数组的mex(最小排除)是不属于该数组的最小非负整数。

思路:因为不必要最小化k,所以尝试达到0,1,2…n-1这样的数组即可。
重复以下步骤:如果,mex==n,对任何一个不匹配的点进行操作,如果mex

#include
#include
#include
#include
using namespace std;
int n, m,t;
int a[1005];
int cheak()
{
	for (int i = 1; i <= n; i++) 
	{
		if (a[i] != i - 1) 
			return 0;
	}
	return 1;
}
int work()
{
	int used[1005];
	memset(used, 0, sizeof(used));
	for (int i = 1; i <= n; i++)
		used[a[i]] = 1;
	for (int i = 0; i <= n; i++)
		if (!used[i])
			return i;
}
int main()
{
	cin >> t;
	while (t--)
	{
		cin >> n;
		vector< int > v;
		for (int i = 1; i <= n; i++)
			cin >> a[i];
		while (1)
		{
			if (cheak())
			  break;
			int mex = work();
			if (mex == n)
			{
				for (int i = 1; i <= n; i++)
				{
					if (a[i] != i - 1)
					{
						a[i] = mex;
						v.push_back(i);
						break;//注意要break
					}
				}
			}
			else
			{
				a[mex + 1] = mex;
				v.push_back(mex + 1);
			}
		}
		cout << v.size() << endl;;
		for (int i = 0; i < v.size(); i++)
			cout << v[i]<<" ";
		cout << endl;
	}
}

你可能感兴趣的:(补题记录)