2050编程竞赛五题弱鸡做出题目总汇 (1001,1002,1003,1004,1006)
先说一下有什么疑问的话直接下方留言就好~~弱鸡我一定尽力回复~
开场白
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 12147 Accepted Submission(s): 3502
Problem Description
来自世界各地的年青人在 https://2050.org.cn 握手团聚, 他们是航空航天的新生代,编程大赛的优胜者,35岁以下的创新者,科技公司的创始人,展望未来的科学家,天马行空的艺术家...... TA们期待在这里与所有人分享交流,给彼此灵感,给未来答案。
我们想要用10个题目,大声喊出年青人的声音。我们希望和大家一起用技术创造一个更好的2050。
第一道题目,我们来玩一个数字游戏。
给出一个数字 n,我们想知道 n 是不是若干个 2050 依次拼接起来的。
Input
第一行一个正整数 T (T≤10) 表示数据组数。
对于每组数据,一行一个正整数 n (1≤n≤10100000)。
Output
对于每组数据,Yes 表示 n 是若干个 2050 依次拼接起来的,No 表示不是。
Sample Input
2 2050 205020
Sample Output
Yes No
#include<bits/stdc++.h>
using namespace std;
int main() {
int te;
ios::sync_with_stdio(0);
string m; cin >> te;
while (te--) {
cin >> m;
int len = m.length();
if (m.length() % 4 != 0) {
cout << "No" << endl;
continue;
}
else {
int k = m.length() / 4;
int pot = 0;
for (int i = 0; i < k; i++) {
if (m[i * 4 + 0] != '2' || m[i * 4 + 1] != '0' || m[i * 4 + 2] != '5' || m[i * 4 + 3] != '0') {
pot = 1; break;
}
}
if (pot) {
cout << "No" << endl;
}
else {
cout << "Yes" << endl;
}
}
}
return 0;
}
时间间隔
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7501 Accepted Submission(s): 2735
Problem Description
2019年1月1日,在云栖出现了可能是全世界最长的以秒为单位的倒计时装置:九亿多秒倒计时,直到2050年。
给出一个时间S,我们想知道S距离2050年1月1日0点0时0分多少秒。
因为答案可能很大,请输出答案模100的值。
Input
第一行一个正整数 T (1≤T≤100000) 表示数据组数。
对于每组数据,一行一个字符串表示时间。
时间格式为:YYYY-MM-DD HH:MM:SS,分别表示年、月、日、时,分、秒。
输入的时间保证都在2019年1月1日以后(包含当天)。
Output
对于每组数据输出一行一个整数表示答案。
Sample Input
1 2019-01-01 00:00:00
Sample Output
0
Source
Test Contest
先说一下我第二题读错提了。。。。。没联系到时间跟%100之间的关系。。。暴力了一个小时。
应该直接对分钟和秒进行计算并%100.
#include<bits/stdc++.h>
using namespace std;
vector<int>G[1005];
int Years(int begin, int end)
{
int begin4 = (begin - 1) / 4;
int begin100 = (begin - 1) / 100;
int begin400 = (begin - 1) / 400;
int left = begin4 - begin100 + begin400;
int end4 = end / 4;
int end100 = end / 100;
int end400 = end / 400;
int right = end4 - end100 + end400;
int result = right - left;
return result;
}
int riqi[12][2] = { 0, 31,60,91,121,152,182,213,244,274,305,335,0,31,59,90,120,151,181,212,243,273,304,334 };
long long go(int a,int b,int c,int d,int e,int f) {
/*
long long run = Years(a, 2049) % 10;
long long days = ((2049 - a) * 365 + run) % 10;*/
long long days = 0, tmp = 0;
if ((a % 4 == 0 && a % 100 != 0) || a % 400 == 0) {
tmp = 1LL * 366 * 24 * 60 * 60;
}
else {
tmp = 1LL * 365 * 24 * 60 * 60;
}
if ((a % 4 == 0 && a % 100 != 0) || a % 400 == 0) {
days += riqi[b - 1][0] + c;
}
else {
days += riqi[b - 1][1] + c;
// cout << riqi[b - 1][1] << " " << c << endl;
}
days--;
days = days * 24 * 60 * 60 + d * 60 * 60 + e * 60 + f;
// cout << days << " " << tmp << endl;
tmp -= days; tmp %= 100;
a++;
long long ans = tmp;
if (a != 2050) {
int *** = Years(a, 2049);
ans = ans + 1LL * (2049 - a + 1 - ***) * 365 * 24 * 60 * 60 +
(***) * 366 * 24 * 60 * 60;
ans %= 100;
}
return ans;
}
int main() {
int te;
ios::sync_with_stdio(0);
cin >> te;
while (te--) {
int a, b, c, d, e, f; char t;
cin >> a >> t >> b >> t >> c; cin >> d >> t >> e >> t >> f;
cout << go(a, b, c, d, e, f) << endl;
}
return 0;
}
分宿舍
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5502 Accepted Submission(s): 704
Problem Description
“那天TA说TA要来,于是我就来啦。
那天我说我要来,于是你就来啦。
TA看到了什么?
你又看到了什么?
我看到你们在一起,我是真的很happy:)
太阳在哪里啊?
就在早上七八点。
太阳在哪里啊?
就在云的栖息地!”
——2050主题曲
2050的线下活动吸引了很多心怀梦想的年轻人。
小伙们打算组团去参加。他们一共有 n+m+2k 个人,包括 n+k 个男生,m+k 个女生,其中 k 对男女生为异性情侣,现在他们要找房间住。房间有三种类型,双人间 a 元一间,三人间 b 元一间,这两种只能同性一起住。情侣间能住一对异性情侣,一间 c 元。除了情侣间以外,其他房间都可以不住满。
求最少花多少钱,能让小伙伴们都有地方住。
Input
第一行一个整数 T (1≤T≤50) 表示数据组数。
接下来 T 组数据,每组数据一行 6 个整数 n,m,k,a,b,c,其中 0≤n,m,k≤103,0≤a,b,c≤109。
Output
对于每组数据输出一行一个数,表示所有人住下来所需要的最小花费。
Sample Input
2 3 0 1 1 3 3 3 3 2 1 6 2
Sample Output
3 6
dp,dp[i][j][k]表示给第i个人分到第j种宿舍(二人或三人),加上之后变为k人的情况下的最小消费。
对n+k和m+k进行dp,最后进行枚举 让i对情侣住情侣房的数量 的情况下的最小消费就好。
#include<bits/stdc++.h>
using namespace std;
const long long inf = 0x3f3f3f3f3f3f3f3f;
long long dpboy[4005][2][4], dpgi[4005][2][4];
void go(long long dp[][2][4],int n,int v2,int v3) {
for (int i = 2; i <= n; i++) {
long long min0 = inf, min1 = inf;
for (int j = 1; j <= 2; j++)
min0 = min(min0, dp[i - 1][0][j]);
for (int j = 1; j <= 3; j++)
min1 = min(min1, dp[i - 1][1][j]);
dp[i][0][1] = min(min0, min1) + v2;
dp[i][0][2] = dp[i - 1][0][1];
dp[i][1][1] = min(min0, min1) + v3;
dp[i][1][2] = dp[i - 1][1][1];dp[i][1][3] = dp[i - 1][1][2];
}
}
int main() {
int te;
ios::sync_with_stdio(0);
cin >> te;
while (te--) {
for (int i = 0; i < 4005; i++) {
for (int j = 0; j < 4; j++) {
dpboy[i][0][j] = dpboy[i][1][j] = dpgi[i][0][j] = dpgi[i][1][j] = inf;
}
}
int a, b, c, v2, v3, v1;
cin >> a >> b >> c >> v2 >> v3 >> v1;
dpboy[1][0][1] = v2; dpboy[1][1][1] = v3; dpgi[1][0][1] = v2;dpgi[1][1][1] = v3;
go(dpboy, a + c, v2, v3);go(dpgi, b + c, v2, v3);
dpboy[0][0][0] = 0; dpboy[0][0][1] = 0; dpgi[0][0][0] = 0; dpgi[0][0][1] = 0;
long long min0 = inf, min1 = inf;
for (int j = 1; j <= 2; j++)
min0 = min(min0, dpboy[a + c][0][j]);
for (int j = 1; j <= 3; j++)
min0 = min(min0, dpboy[a + c][1][j]);
for (int j = 1; j <= 2; j++)
min1 = min(min1, dpgi[b + c][0][j]);
for (int j = 1; j <= 3; j++)
min1 = min(min1, dpgi[b + c][1][j]);
long long ans = min0 + min1;
for (int i = 1; i <= c; i++) {
long long min0 = inf, min1 = inf;
for (int j = 1; j <= 2; j++)
min0 = min(min0, dpboy[a + c - i][0][j]);
for (int j = 1; j <= 3; j++)
min0 = min(min0, dpboy[a + c - i][1][j]);
for (int j = 1; j <= 2; j++)
min1 = min(min1, dpgi[b + c - i][0][j]);
for (int j = 1; j <= 3; j++)
min1 = min(min1, dpgi[b + c - i][1][j]);
ans = min(ans, 1LL * i*v1 + min0 + min1);
}
cout << ans << endl;
}
return 0;
}
PASS
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5635 Accepted Submission(s): 2957
Problem Description
有 n 个选手参加了 2050 编程竞赛,他们属于 m 个学校,学校的编号为 1 到 m,2050 编程竞赛的 PASS 奖励资格如下:对于一个学校,如果它有 x 个学生参赛,它的参赛学生里成绩最好的 ⌊xk⌋ 人里,每有一个人总排名在前 50% 内(包括50%),就奖励一个 PASS。
现在给出每个选手所属的学校和它的排名(假设没有平手),请你帮主办方算一下一共发出了几个 PASS。
Input
第一行一个正整数 T (1≤T≤10) 表示数据组数。
接下来 T 组数据,对于每组数据:
第一行三个正整数 n,m,k (1≤n≤104,1≤m≤103,2≤k≤20)。
第二行 n 个数,按照成绩从好到差给出 n 个选手所属的学校。
Output
对于每组数据输出一行一个整数表示答案。
Sample Input
2 6 2 2 1 1 2 1 2 2 8 2 2 1 1 2 1 2 2 2 2
Sample Output
2 2
暴力
#include<bits/stdc++.h>
using namespace std;
vector<int>G[1005];
int main() {
int te;
ios::sync_with_stdio(0);
cin >> te;
while (te--) {
for (int i = 0; i < 1005; i++)G[i].clear();
int n, m, k;
cin >> n >> m >> k;
int need = n / 2;
for (int i = 1; i <= n; i++) {
int id; cin >> id;
G[id].push_back(i);
}
int ans = 0;
for (int i = 0; i < 1005; i++) {
int sz = G[i].size();
int can = sz / k;
for (int j = 0; j < can; j++) {
if (G[i][j] <= need) {
ans++;
}
}
}
cout << ans << endl;
}
return 0;
}
冰水挑战
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2397 Accepted Submission(s): 429
Problem Description
Polar Bear Pitching helps you crystallize your message.
The stage could not be any cooler, and we mean literally:
a hole cut through the ice in the frozen Baltic Sea.
2050有一项很有挑战的活动 —— Polar Bear Pitching 。
体验人跳入冰水中讲述自己的恐惧,改变以及梦想。这是没有时间限制的演讲,就看你能在冰水中呆多久!
现在,我们要依次面对 n 个冰水挑战,每个挑战你都可以选择接受或不接受。接受第 i 个挑战会让你丧失 ai点体力,因为每个挑战所处的环境不同,如果你要挑战它,在挑战它之前你的体力 x 会变成 min(x,bi),当你完成这个挑战的时候,你的体力会变成 x−ai,体力任何时候不允许小于等于 0,无论你是否接受第 i 个挑战,在这个挑战结束以后你的体力都会增加 ci。
现在我们想知道最多可以完成多少个挑战。
Input
第一行一个正整数 T (T≤50) 表示数据组数。
接下来 T 组数据,每组第一行两个正整数 n,c (1≤n≤103,1≤c≤109),表示挑战的数量和初始体力,接下来 n 行,每行三个非负整数 ai,bi,ci(0≤ai,bi,ci≤109)。
Output
对于每组数据输出一行一个数,表示你最多能完成几个挑战。
Sample Input
2 3 10 1 2 0 4 8 3 6 10 1 2 1 1 1 1 1 1 1
Sample Output
2 0
进行dp,dp[i][j]表示经过了i题以后(不一定做),一共做了j题的情况下的最大体力保存是多少。
然后到最后进行枚举看做几道数量题的情况下最先成立就行。
#include<bits/stdc++.h>
using namespace std;
const long long inf = 0x3f3f3f3f3f3f3f3f;
long long dp[1005][1005];
long long a[1005], b[1005], c[1005];
int main() {
int te;
ios::sync_with_stdio(0);
cin >> te;
while (te--) {
int n, m;
cin >> n >> m;
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= n; j++) {
dp[i][j] = -inf;
}
}
for (int i = 1; i <= n; i++)
cin >> a[i] >> b[i] >> c[i];
dp[0][0] = m;
c[0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= i; j++) {
long long go = -inf;
if (j != 0 && min(c[i - 1] + dp[i - 1][j - 1], b[i]) > a[i]) {
go = min(dp[i - 1][j - 1] + c[i - 1], b[i]) - a[i];
}
dp[i][j] = max(dp[i - 1][j] + c[i - 1], go);
}
}
for (int i = n; i >= 0; i--) {
if (dp[n][i] > 0) {
cout << i << endl;
break;
}
}
}
return 0;
}