week13 必做题(A - TT 的神秘任务1 + B - TT 的神秘任务2 + C - TT 的奖励)

这篇博客详细解析了TT的三道编程任务:A题通过分类讨论解决奇偶性问题;B题利用数学性质找到不能被整除的数;C题采用动态规划求解猫猫掉落的最大数量。每题均包含题目、样例及代码实现。
摘要由CSDN通过智能技术生成

A - TT 的神秘任务1

题目

样例输入

8
10 3
100 4
8 7
97 2
8 8
3 10
5 3
1000000000 9

样例输出

YES
4 2 4
YES
55 5 5 35
NO
NO
YES
1 1 1 1 1 1 1 1
NO
YES
3 1 1
YES
111111110 111111110 111111110 111111110 111111110 111111110 111111110 111111110 111111120

 

思路

暴力地进行分类讨论。

奇数 * 奇数 = 奇数,由此可知当 n 为奇数时,k必须为偶数;

其余情况,根据n、k的奇偶性进行分类,

对于 n 过小的情况直接输出"NO",如果满足条件,前(k - 1)个数输出1或2,第k个数输出n与前(k - 1)个数的差值。

 

代码

#include<iostream>
using namespace std;

int main()
{
	int T;
	int n, k;
	cin >> T;
	for (int i = 0; i < T; i++)
	{
		//cout << "i:" << i << endl;
		cin >> n >> k;
		if (k > n)
		{
			cout << "NO" << endl;
			continue;
		}

		else if (n % 2 == 1)//和为奇数
		{
			if (k % 2 == 0)
			{
				cout << "NO" << endl;
				continue;
			}
			else
			{
				cout << "YES" << endl;
				for (int j = 1; j < k; j++)
					cout << 1 << " ";
				cout << n - k + 1 << endl;
				continue;
			}
		}
		else
		{
			if (k % 2 == 1)//必须是偶数
			{
				if (n < 2 * k)
				{
					cout << "NO" << endl;
					continue;
				}
				else
				{
					cout << "YES" << endl;
					for (int j = 1; j < k; j++)
						cout << 2 << " ";
					cout << n - 2 * (k - 1) << endl;
					continue;
				}
			}
			else
			{
				cout << "YES" << endl;
				for (int j = 1; j < k; j++)
					cout << 1 << " ";
				cout << n - k + 1 << endl;
				continue;
			}
		}
	}
	system("pause");
}

 

 

 

 

B - TT 的神秘任务2

题目

样例输入

6
3 7
4 12
2 1000000000
7 97
1000000000 1000000000
2 1

样例输出

10
15
1999999999
113
1000000001
1

 

思路

分析可知,n的倍数可以被整除,因此每n 个数中有(n - 1)个数不能被整除。

算出 k 中有多少(n - 1)个数,将商乘 n 再加上余数,如果余数恰好为零,答案往前回退一步(因为多加了一个可以被整除的 n 的倍数)。

 

代码

#include<iostream>
using namespace std;

int main()
{
	int T, n, k, ans, num, yu;
	cin >> T;
	for (int i = 0; i < T; i++)
	{
		cin >> n >> k;
		num = k / (n - 1);
		yu = k % (n - 1);
		ans = num * n + yu;
		if (yu == 0) ans--;
		cout << ans << endl;
	}
	system("Pause");
}

 

 

 

 

 

C - TT 的奖励

题目

样例输入

6
5 1
4 1
6 1
7 2
7 2
8 3
0

样例输出

4

 

思路

一个动态规划问题。

用f[ i ][ j ]表示第 i 秒,j 位置掉落的猫猫数量。

初始化:

输入a、b,将 f [ b ][ a ] 初始化为每一秒每一个点上掉落的猫猫数目。

除去 f [ 1 ][ 4 ]、f [ 1 ][ 5 ]、f [ 1 ][ 6 ],其他f [ 1 ][ x ] = 0,因为其他位置掉落的猫猫一定接不到。

状态转移方程:

第 i 秒,是从第(i - 1)秒转移过来的,而第 j 个位置只能从 j / j + 1/ j - 1 转移而来。

f[  i ][ j ] += max{ f [ i - 1 ][ j ],  f [i - 1][j - 1],  f[i - 1][j + 1] };

结果:

最后一秒的最大猫猫数。

 

代码

#include<iostream>
#include<algorithm>
using namespace std;
int f[100010][12];//秒,位置
int m, a, b, tim, ans;

int main()
{
	while (1)
	{
		cin >> m;
		if (m == 0) break;
		memset(f, 0, sizeof f);
		ans = tim = 0;
		for (int i = 0; i < m; i++)
		{
			cin >> a >> b;
			f[b][a]++;
			if (tim < b) tim = b;
		}
		for (int i = 0; i < 12; i++)
			if (i != 4 && i != 5 && i != 6)
				f[1][i] = 0;

		for (int i = 2; i <= tim; i++)
		{
			f[i][0] += max(f[i - 1][1], f[i - 1][0]);
			for (int j = 1; j < 10; j++)
				f[i][j] += max(f[i - 1][j], max(f[i - 1][j - 1], f[i - 1][j + 1]));
			f[i][10] += max(f[i - 1][9], f[i - 1][10]);
		}

		for (int i = 0; i <= 10; i++)
			if (ans < f[tim][i]) ans = f[tim][i];

		cout << ans << endl;

	}
	system("Pause");
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值