Round #550 (Div. 3)

难题不会做,只能做做简单题才能维持维持生活。。。
题目链接,官方Tutorial

1、Diverse Strings

题目意思:给一个字符串,如果没有重复元素并且其中的元素都是在字母表中相邻,输出Yes
我的思路:先用散列判断有没有重复元素,之后遍历字符串,任意两个字符之间的距离必须小于字符串长度,否则就不是在字母表中相邻。

#define _CRT_SECURE_NO_WARNINGS

#include 
#include 
#include 
#include 

using namespace std;

bool depu(string str)
{
	int len = str.length();
	int hash[500] = { 0 };

	for (int i = 0; i < len; i++)
	{
		hash[str[i]]++;
		if (hash[str[i]] > 1)
			return false;
	}

	return true;
}

bool distance(string str)
{
	int len = str.length();

	for(int i = 0;i < len;i++)
		for (int j = i + 1; j < len; j++)
		{
			if (abs(str[j] - str[i]) >= len)
				return false;
		}

	return true;
}

int main()
{
	int n;
	string str;

	scanf("%d", &n);

	while (n--)
	{
		cin >> str;

		if (depu(str) && distance(str))
			printf("Yes\n");
		else
			printf("No\n");
	}

	return 0;
}
  • 读取数据时遇到点小问题:scanf("%s",str)读取字符串后发现字符串为空
    scanf("%s", &str[0]);可以正常读取。
    但是不论哪种方式,len = str.length()得到的len都是0。
    处理string对象还是用cin,想用scanf可以定义字符数组。

复杂度 O ( n 2 ) O(n^2) O(n2)。其实可以对字符串排序,复杂度可以降到 O ( n l o g n ) O(nlogn) O(nlogn)

#define _CRT_SECURE_NO_WARNINGS

#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

int main()
{
	int n;
	string str;
	map mp;

	scanf("%d", &n);

	while (n--)
	{
		bool flag = true;
		cin >> str;
		int len = str.size();

		for (int i = 0; i < len; i++)   //先判断重复
		{
			if (mp[str[i]] > 1)
			{
				printf("No\n");
				flag = false;
				break;
			}
			mp[str[i]]++;
		}

		for (char i = 'a'; i <= 'z'; i++)
		{
			mp[i] = 0;
		}

		if (!flag)
			continue;
		
		flag = true;
		/*能走到这一步,必然没有重复元素*/
		sort(str.begin(), str.end());
		for (int i = 1; i < len; i++)
		{
			if (str[i] - str[i - 1] != 1)
			{
				printf("No\n");
				flag = false;
				break;
			}
		}
		if (flag)
			printf("Yes\n");

	}

	return 0;
}

2、Parity Alternated Deletions

题目意思:给一个数组,交替删除奇数和偶数,求最后剩下的元素和的最小值。
我的思路:统计奇偶数的个数,如果个数差 t m p tmp tmp小于2,则最终所有元素都可以删掉,输出0;否则,排序后输出前 t m p − 1 tmp-1 tmp1个奇数或偶数。

#include 
#include 
#include 
#include 

using namespace std;

//我的思路是排序后遍历,看奇数和偶数的个数关系
int main()
{
	vector s;
	int n, a;
	int res = 0, cntOdd = 0, cntEven = 0;

	cin >> n;
	for(int i = 0;i < n;i++)
	{
		cin >> a;
		if (a % 2)
		{
			cntOdd++;
		}
		else
		{
			cntEven++;
		}
		s.push_back(a);
	}

	sort(s.begin(), s.end());

	int tmp = cntOdd - cntEven;
	
	if (tmp > 1)  //奇数比偶数多至少2个
	{
		int cnt = 0, j = 0;

		//从前往后找到tmp - 1个奇数,求和
		while (cnt < tmp - 1)
		{
			if (s[j] % 2)
			{
				res += s[j];
				cnt++;
			}
			j++;
		}
	}
	else if(tmp < -1)
	{
		int cnt = 0, j = 0;
		
		while (cnt < abs(tmp) - 1)
		{
			if (s[j] % 2 == 0)
			{
				res += s[j];
				cnt++;
			}
			j++;
		}
	}
		
	cout << res << endl;

	return 0;
}

3、Two Shuffled Sequences

题目意思:给一个乱序数组,判断是否能把该数组划分为一个严格增和一个严格减的子数组,并且输出相应的子数组序列。
我的思路:如果某元素出现了3次及以上,必然不可以;排序,将重复元素分别划进两个子数组即可。

#include 
#include 
#include 
#include 

using namespace std;

#define MAXN 200000 + 10

int hashtable[MAXN] = { 0 };

int main()
{
	int n;
	bool flag = false;  //标记某个元素是否出现3次以上
	vector s;
	cin >> n;

	for (int i = 0; i < n; i++)
	{
		int x;
		cin >> x;
		s.push_back(x);
		hashtable[x]++;
		if (hashtable[x] >= 3)
		{
			flag = true;
		}
	}

	if (1 == n)
	{
		cout << "YES" << endl << "1" << endl << s[0] << endl << "0" << endl;
	}
	else if (flag)
	{
		cout << "NO" << endl;
	}
	else
	{
		cout << "YES" << endl;
		sort(s.begin(), s.end());
		vector inc, dec;
		int incNum = 0, decNum = 0;

		for (int i = 0; i < n; i++)
		{
			if (hashtable[s[i]] > 1)
			{
				decNum++;
				dec.push_back(s[i]);
				hashtable[s[i]]--;
			}
			else if(hashtable[s[i]] == 1)
			{
				incNum++;
				inc.push_back(s[i]);
			}
		}

		cout << incNum << endl;
		for (auto j = inc.begin();j != inc.end();j++)
		{
			cout << *j;
			if (j < inc.end() - 1)
				cout << " ";
		}
		cout << endl << decNum << endl;
		for (auto j = dec.rbegin(); j != dec.rend(); j++)
		{
			cout << *j;
			if (j < dec.rend() - 1)
				cout << " ";
		}
		cout << endl;
	}


	return 0;
}

你可能感兴趣的:(Codeforces)