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");
}