加载中...

SDTBU-ACM集训队暑期集训---个人赛 6


第一题

题目: Problem - 1629A - Codeforces

题意:

有n个数,每个数有两个属性Wi和Vi,给定我们一个初始值k。如果当前某个数的Wi 小于k,那么就可以把Vi加到k上,求k最大值为多少。

输入格式

输入包含多个样例,第一行是一个整数t,代表有t个整数。

每个样例第一行是两个整数n和k。

每个样例第二行有n个整数,分别为W1 ~ Wn

每个样例第三行有n个整数,分别为V1 ~ Vn

数据范围

1 ≤ t ≤ 100

1 ≤ n ≤ 100, 1 ≤ k ≤ 1000

1 ≤ Wi, Vi ≤ 1000

输出格式

输出一个整数。

输入样例:

4
3 10
20 30 10
9 100 10
5 1
1 1 5 1 1
1 1 1 1 1
5 1
2 2 2 2 2
100 100 100 100 100
5 8
128 64 32 16 8
128 64 32 16 8

输出样例:

29
6
1
256

思路:

  • 水题,将所有数字按属性W从小到大排序,循环判断k是否大于Wi,如果大于就加上Vi,否则退出。

代码:

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<unordered_map>
#include<queue>
#include<cmath>
#include<map>

using namespace std;

#define PII pair<int,int>
#define ll long long

const int N = 150;

int n,k;
PII p[N];

int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		cin >> n >> k;
		for (int i = 1; i <= n; ++i)cin >> p[i].first;
		for (int i = 1; i <= n; ++i)cin >> p[i].second;

		sort(p + 1, p + n + 1);

		for (int i = 1; i <= n; ++i)
		{
			if (p[i].first <= k)k += p[i].second;
			else break;
		}
		cout << k << endl;

	}

	return 0;
}

第二题

题目: Problem - 1629B - Codeforces

题意:

给定我们一个集合和k次操作,集合中的数为区间[l, r]中的整数,每次操作可以从集合中取出两个数,并将两个数的积加入到集合中,直到k次操作结束或者集合中只有一个数。如果结束后集合中所有的数的最大公因数大于1,输出 YES ,否则输出 NO

输入格式

输入包含多个样例,第一行是一个整数t,表示有t个样例。

每个样例只有一行,有三个数,l,r,k。

输出格式

一个整数,表示第几个字符串。

数据范围

1≤ N ≤105

YESNO

输入样例:

9
1 1 0
3 5 1
13 13 0
4 4 0
3 7 4
4 10 3
2 4 0
1 7 3
1 5 3

输出样例:

NO
NO
YES
YES
YES
YES
NO
NO
YES

思路:

  • 看上去好像很难(一眼以为不会,就去做D题了,结果D题连WA两次,一看榜发现B题通过率很高,痛!),其实很简单。
  • 考虑这样一个问题,什么时候集合中所有数的最大公因子大于1,显然当集合中只有1个数且不为1或者集合中全部为偶数时一定符合。前者的最大公因子就是这个数本身,后者最小的公因子是2。
  • 那么问题就转化为k次操作是否能将所有的所有的奇数转化为偶数,怎么转化?奇数乘奇数得到的是奇数,奇数乘偶数得到的是偶数。每次操作可以去掉一个奇数,直接比较集合中的奇数和k谁大就可以了。

代码:

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<unordered_map>
#include<queue>
#include<cmath>
#include<map>

using namespace std;

#define PII pair<int,int>
#define ll long long

const int N = 150;

int n;

int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		int l, r, k;
		bool flag = false;
		cin >> l >> r >> k;
		if (l == r && l != 1)flag = true;

		int m = (r - l + 1);
		if (m % 2 == 0)m /= 2;
		else if (l % 2 == 0)m /= 2;
		else m = m / 2 + 1;
		if (m <= k || flag == true)cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	return 0;
}

第四题

题目: Problem - 1629D - Codeforces

题意:

有n个字符串,我们可以删除任意个字符串,问能否在不调整字符串的顺序的前提下,使得剩下的字符串成为回文串。

输入格式

输入包含多个样例,第一行是一个整数t,表示有t个样例。

每个样例第一行是一个整数n,表示有n个字符串。

接下来有n行字符串,每个字符串的长度为1~3。

输出格式

YESNO

数据范围

1 ≤ t ≤ 100

1 ≤ n ≤ 105

输入样例:

6
5
zx
ab
cc
zx
ba
2
ab
bad
4
co
def
orc
es
3
a
b
c
3
ab
cd
cba
2
ab
ab

输出样例:

YES
NO
NO
YES
YES
NO

思路:

  • 很容易想到我们可以用map来存出现过的字符串,每个字符串根据串的长度分类讨论:
    • 如果字符串长度为1,显然它的逆序串就是本身,输出 YES
    • 如果字符串长度为2,那么需要判断是否可以和长度为2或者长度为3的字符串组成回文串。
    • 字符串长度为3,需要判断是否可以和长度为2或者长度为3的字符串组成回文串。同时要将字符串的前两个字符取出存好,以便于和后面长度为2的字符串组成回文。
  • 这里有个大坑,从长度为3的串中取出的子串不能和初始长度为2的串存在一起,否则将会造成混乱,比如会将abc,dba视为回文串。

代码:

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<unordered_map>
#include<queue>
#include<cmath>
#include<map>

using namespace std;

#define PII pair<int,int>
#define ll long long

const int N = 150;

int n;

int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		cin >> n;
		bool flag = false;
		//要将长度为2的字符串用两个map来存,作用主要体现在将2+3和3+3的匹配区分开。
		//如果用一个map存,会出现混乱,比如abc,dba会判断为回文子串
		unordered_map<string, int>p23,pp2;//前者存原始长度为2和3的字符串,后者存从长度为3的字符串中截取的字符串
		for (int i = 1; i <= n; ++i)
		{
			string s;
			cin >> s;
			if (s.size() == 1)flag = true;
			else if (s.size()==2)
			{
				string s1 = s;
				reverse(s1.begin(),s1.end());
				if (p23[s1]||pp2[s1] || s1[0] == s1[1])flag = true;
				
				p23[s]++;
			}
			else
			{
				string s1 = s;
				reverse(s1.begin(), s1.end());
				if (p23[s1]||s1[0]==s1[2])flag = true;
				
				string s2 = s.substr(1, 2);
				reverse(s2.begin(), s2.end());
				if (p23[s2])flag = true;
				
				s2 = s.substr(0, 2);
				pp2[s2]=p23[s]=1;
			}
		}
		if (flag) cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	return 0;
}

文章作者: 心意
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 心意 !
评论
  目录