牛客练习赛16 B-漂亮的树,C-任意点

链接: https://www.nowcoder.com/acm/contest/84/B
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

街上有n棵树,标号为1...n,第i棵树的高度为a i
定义这n棵树是漂亮的,当且仅当
    1. 对于所有的i,a i=a n-i+1
    2. 对于1 <= i < n / 2 (不是整除),a i + 1= a i + 1;
比如说 “2 3 4 5 5 4 3 2”和“1 2 3 2 1”是漂亮的而“1 3 3 1”和“1 2 3 1”不是。
现在请问最少修改几棵树的高度(可以变大也可以变小),使得这些树是漂亮的。

输入描述:

第一行一个整数n表示树的数量( 1 <= n <= 100,000)。
第二行n个整数表示树的高度( 1 <= ai <= 100,000)。

输出描述:

输出一个整数表示最少修改树的高度的数目。

解题思路:这个题看着真的很懵,没有思路一开始,后来也是看的别人的解题草懂的,其实很简单,就一个难想到的点就是下标减下标对应的值结果出现的次数最多的值就是要求的不需要改变的元素。答案就是n-不需要改的元素个数。这里用一个数组count[]来表示下标为i的差值,即a[i]-i,但是因为a[i]-i的值有可能是负数,所以我们考虑到最大的负数为-2*maxn,所以我们这个count[]数组平均都加上2*maxn,这样就避免了负数。

AC代码:

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int n;
int temp;
const int maxn = 1e5 + 5;
int a[maxn];
int cou[maxn*2]; //用来存储i-a[i]的个数数组
int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	memset(cou, 0, sizeof(cou));
	int temp = (n+1) / 2;
	for (int i = 1; i <= temp; i++)
	{
		cou[a[i] - i + maxn]++;
	}
	for (int i = temp + 1; i <= n; i++)
	{
		cou[a[i] - (n - i + 1) + maxn]++;
	}
	int ma = 0;
	for (int i = 1; i <= 2 * maxn; i++)
	{
		ma = max(ma, cou[i]); //不需要改变的最多的个数
	}
	cout << n - ma << endl;
	return 0;
}

C任意点

链接:https://www.nowcoder.com/acm/contest/84/C

来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

平面上有若干个点,从每个点出发,你可以往东南西北任意方向走,直到碰到另一个点,然后才可以改变方向。
请问至少需要加多少个点,使得点对之间互相可以到达。

输入描述:

第一行一个整数n表示点数( 1 <= n <= 100)。
第二行n行,每行两个整数xi, yi表示坐标( 1 <= xi, y<= 1000)。
y轴正方向为北,x轴正方形为东。

输出描述:

输出一个整数表示最少需要加的点的数目。

解题思路:其实就是求连通图的个数。然后加边使得只有一个连通图。BFS广度优先搜索,从第一个点开始进行搜索,将所有可以连到的点都标记出来,然后求出所有互相不连通的个数,即在n个小连通图之间加上n-1条边使得n个小连通图连通。

AC代码:

#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 1000 + 100;
int n;
struct Node
{
	int x, y;
};
vector<Node>vec;
bool f[maxn];
queue<int>Q;
void bfs(int x)
{
	f[x] = 1;
	Q.push(x);
	while (!Q.empty())
	{
		int i = Q.front();
		Q.pop();
		for (int j = 0; j < n; j++)
		{
			if (f[j] == 0)
			{
				if (vec[i].x == vec[j].x || vec[i].y == vec[j].y)
				{
					f[j] = 1;
					Q.push(j);
				}
			}
		}
	}
	return;
}
int main()
{
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		Node now;
		cin >> now.x >> now.y;
		vec.push_back(now);
	}
	memset(f, 0, sizeof(f));
	int ans = 0;
	for (int i = 0; i < n; i++)
	{
		if (f[i] == false)
		{
			bfs(i);
			ans++;
		}
	}
	cout << ans-1 << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40129237/article/details/80145601