RC-u1 热҈热҈热҈
分数 10
全屏浏览
切换布局
作者 DAI, Longao
单位 杭州百腾教育科技有限公司
热҈热҈热҈……最近热得打的字都出汗了!
幸好某连锁餐厅开启了气温大于等于 35 度即可获得一杯免费雪碧的活动。但不知为何,在每个星期四的时候,这个活动会暂停一天……
现在给定连续的若干天的气温情况以及给定的第一天是星期几,请你算出有多少天你可以喝到免费的雪碧,又有多少天是因为星期四而导致你喝不到雪碧的。
输入格式:
输入第一行是两个正整数 N, W (1≤N≤50,1≤W≤7),表示给定连续的 N 天,下面给定的第一天是星期 W(7 等于星期天)。
接下来的一行给出 N 个用一个空格隔开的、小于 60 的整数,第 i 个数表示第 i 天的温度。保证温度大于等于 -273 度。
输出格式:
输出两个数,第一个是你能喝到免费雪碧的天数,第二个是你本来能喝到免费雪碧、但因为是星期四而无法喝到的天数。
输入样例:
15 3 33 35 34 36 37 40 32 31 30 29 28 29 33 38 40
输出样例:
5 1
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
栈限制
8192 KB
思路:直接模拟
#include "bits/stdc++.h" using namespace std; int main(){ int n, w, x, ans1 =0, ans2 = 0; cin>>n>>w; for(int i = 0; i < n; i++){ cin>>x; if(x >= 35 && w != 4) ans1 ++; else if(x >= 35 && w == 4) ans2 ++; w ++; if(w == 8) w = 1; } cout<<ans1<<" "<<ans2; return 0; }
RC-u2 谁进线下了?
分数 15
全屏浏览
切换布局
作者 DAI, Longao
单位 杭州百腾教育科技有限公司
Xepa Legends 是一个第一人称射击类大逃杀(“吃鸡”)游戏,每轮游戏共有 20 支 3 人小队参加,最后获胜的队伍被称为“捍卫者”。
最近 Xepa Legends 举行了亚太地区南赛区的线上比赛,争夺 7 个前往德国曼海姆参加线下赛的资格,国内共有 14 支队伍参与到了其中。因为比赛十分激烈,直到最后谁进了线下仍有巨大的疑问。小 K 喜欢的国内知名战队 DreamTear 因其队内选手杀马特表现不佳,正好卡在出线分数前后,请你赶紧帮帮小 K,计算一下最后的分数情况,看看他喜欢的战队出线了没有吧!
Xepa Legends 的比赛共进行 N 场游戏,在每场游戏中,每支队伍在游戏中会获得一个排名和一个杀敌数(击败其他队伍玩家的数量),一支队伍在一场游戏的得分为杀敌数+排名分,排名分由队伍当场的排名根据以下表格求得:
排名 分数 第一名 12 分 第二名 9 分 第三名 7 分 第四名 5 分 第五名 4 分 第六名至第七名 3 分 第八名至第十名 2 分 第十一名至第十五名 1 分 第十六名至第二十名 0 分 例如,
- DreamTear 战队在第三场比赛获得了第三名、有 6 个杀敌数,那么他们将获得 7 + 6 = 13 分;
- KV 战队在第二场比赛获得了第 19 名、有 1 个杀敌数,那么他们将获得 0 + 1 = 1 分;
- SRN 战队在第四场比赛获得了第 1 名、有 9 个杀敌数,那么他们将获得 12 + 9 = 21 分。
注:本题与实际情况无关,所有比赛规则、队伍、队员名称均为虚构。
输入格式:
输入第一行是一个正整数 N (≤20),表示有 N 场比赛。
接下来有 N 部分输入,每部分是一场比赛的情况。对每一场比赛,信息共分 20 行,第 i 行(i=1,⋯,20)给出的两个非负整数 p 和 k 表示第 i 支队伍在这场比赛里获得了第 p 名、杀敌数为 k。
数据保证所有给定的情况中,排名永远大于等于 1 且小于等于 20,杀敌数小于等于 57。
输出格式:
输出 20 行,按编号从小到大依次输出队伍的编号及该队全部游戏结束时的总分。
输入样例:
3 6 2 7 3 11 5 10 1 2 9 5 8 14 3 4 3 1 6 18 1 12 1 20 0 13 0 3 2 16 4 8 1 19 0 9 4 17 1 15 0 8 2 19 1 12 2 1 9 10 1 7 5 18 0 14 0 5 2 4 4 2 5 6 2 16 3 13 1 20 0 3 7 9 3 15 0 17 5 11 3 18 0 5 2 2 9 9 4 4 7 10 3 16 0 1 6 20 0 15 1 6 0 3 6 14 3 7 4 19 0 17 0 8 9 11 0 13 5 12 0
输出样例:
1 9 2 13 3 27 4 30 5 33 6 25 7 4 8 27 9 24 10 12 11 19 12 18 13 8 14 18 15 4 16 17 17 16 18 8 19 12 20 6
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
栈限制
8192 KB
思路:模拟
#include "bits/stdc++.h" using namespace std; int rank1[30] = {0, 12, 9, 7, 5, 4, 3, 3, 2, 2, 2, 1 , 1, 1, 1, 1, 0 ,0,0,0,0}; int score[30]; int main(){ int T, x, y; cin>>T; while(T--){ for(int i = 1; i <= 20; i ++){ cin>>x>>y; score[i] += rank1[x]; score[i] += y; } } for(int i = 1; i <= 20; i ++){ cout<<i<<" "<<score[i]; if(i != 20) cout<<endl; } return 0; }
RC-u3 暖炉与水豚
分数 20
全屏浏览
切换布局
作者 DAI, Longao
单位 杭州百腾教育科技有限公司
PapiCon(@PapilloteContet)出了许多有意思的谜题,其中有一道关于水豚的谜题是这样的:
来源:x.com/PapilloteContet在一个 N×M 的矩阵中有若干水豚以及暖炉,暖炉可以辐射以它自身为中心的 3×3 范围里的水豚,使其变得暖呼呼的。谜题里存在一只冷的要命的水豚,你需要移动其中的一个暖炉,使所有水豚都变得暖呼呼的。
在往下读题前,如果你有兴趣的话,不妨思考一下如何解答这个谜题。(思考结果与题目无关,可跳过。)
这个谜题的关键在于,单纯从图中能看到的暖炉来说是无解的,但如果注意到,第 3 行第 6 列的水豚明明周围没有暖炉,却也处于暖呼呼的状态,就能推测出来图中的那个对话框挡住了一个暖炉,只要移动这个暖炉就可以完成题目的要求。
现在我们将谜题一般化,对于给定的一个 N×M 的矩阵、对应的所有水豚状态、以及能看到的暖炉摆放情况,已知最多只有一只水豚的状态不太对劲(周围没有暖炉却暖呼呼的),你需要推测有哪些格子可能藏了暖炉。一个空格可能藏了暖炉可以理解为:当前空格设置暖炉后整个矩阵的状态会从不合法变为合法。
输入格式:
输入第一行是两个正整数 N, M (1≤N,M≤1000),表示矩阵的大小。
接下来的 N 行,每行有 M 个字符,第 i 行的第 j 个字符表示矩阵中对应位置的状态,其中:
.
表示空格(或者说,看上去是空格的格子);c
表示很冷的水豚;w
表示暖呼呼的水豚;m
表示暖炉。输出格式:
输出若干行,每行两个正整数 r 和 c,表示第 r 行第 c 列有可能藏了一个暖炉,有多个可能时,先按 r 从小到大输出,r 相同时再按 c 从小到大输出。如果没有一个格子可能藏了暖炉, 则在一行中输出
Too cold!
。
行与列均从 1 开始编号。输入样例:
6 8 wm....mw .w..ww.. ..wm.wwm w.w....w .m.c.m.. w.....w.
输出样例:
2 7 3 5 4 6 4 7
代码长度限制
16 KB
Java (javac)
时间限制
800 ms
内存限制
256 MB
其他编译器
时间限制
400 ms
内存限制
64 MB
栈限制
8192 KB
思路:暴力, 看热鼠鼠(水豚)一圈是否有炉子
#include "bits/stdc++.h" using namespace std; int n, m; typedef pair<int, int> PI; int dir[8][2] = {0, 1, 0, -1, 1, 0, -1, 0, -1, -1, 1, 1, -1, 1, 1, -1}; char a[1100][1100]; int vis[1100][1100]; vector<PI> vv; map<PI, int> mp; int ans = 0; void dfs(){ for(int k = 0; k < n; k ++){ for(int h = 0; h < m; h ++){ int x = k, y = h; if(a[x][y] == 'w'){ int flag = 0; for(int i = 0; i < 8; i ++){ int x1 = x + dir[i][0], y1 = y + dir[i][1]; if(x1 < 0 || x1 >= n || y1 < 0 || y1 >= m ) continue; if(a[x1][y1] == 'm'){ flag = 1; break; } } if(!flag) { for(int i = 0; i < 8; i ++){ int x1 = x + dir[i][0], y1 = y + dir[i][1]; if(x1 < 0 || x1 >= n || y1 < 0 || y1 >= m ) continue; if(a[x1][y1] == '.'){ mp[{x1, y1}] ++; } } } } if(a[x][y] == 'c'){ int flag = 0; for(int i = 0; i < 8; i ++){ int x1 = x + dir[i][0], y1 = y + dir[i][1]; if(x1 < 0 || x1 >= n || y1 < 0 || y1 >= m ) continue; if(a[x1][y1] == '.'){ mp[{x1, y1}]= -10000; } } } } } } int main(){ cin>>n>>m; for(int i = 0; i < n; i++){ for(int j = 0; j < m; j ++){ cin>>a[i][j]; } } dfs(); int xx = mp.size(); // cout<<xx<<endl; int ann = 0; for(auto x : mp){ if(x.second >= 1){ vv.push_back({x.first.first + 1, x.first.second + 1}); } } for(int i = 0; i < vv.size(); i ++){ cout<<vv[i].first<<" "<<vv[i].second; if(i != vv.size() - 1) cout<<endl; } if(vv.size() == 0) cout<<"Too cold!" ; return 0; }
RC-u4 章鱼图的判断
分数 25
全屏浏览
切换布局
作者 DAI, Longao
单位 杭州百腾教育科技有限公司
对于无向图 G=(V,E),我们将有且只有一个环的、大于 2 个顶点的无向连通图称之为章鱼图,因为其形状像是一个环(身体)带着若干个树(触手),故得名。
给定一个无向图,请你判断是不是只有一个章鱼子图存在。
输入格式:
输入第一行是一个正整数 T (1≤T≤5),表示数据的组数。
每组数据的第一行是两个正整数 N,M (1≤N,M≤105),表示给定的无向图有 N 个点,M 条边。
接下来的 M 行,每行给出一条边两个端点的顶点编号。注意:顶点编号从 1 开始,并且题目保证任何边不会重复给出,且没有自环。
输出格式:
对于每组数据,如果给定的图里只有一个章鱼子图,则在一行中输出
Yes
和章鱼子图环的大小(及环中顶点数),其间以 1 个空格分隔。否则,则在一行中输出
No
和图中章鱼子图的个数,其间以 1 个空格分隔。输入样例:
3 10 10 1 3 3 5 5 7 7 9 1 2 2 4 2 6 3 8 9 10 1 9 10 10 1 3 3 5 5 7 7 9 9 1 1 2 2 4 4 8 8 10 10 1 10 10 1 3 3 5 5 7 7 9 9 1 2 4 4 8 8 10 10 2 10 6
输出样例:
Yes 5 No 0 No 2
代码长度限制
16 KB
Java (javac)
时间限制
2500 ms
内存限制
512 MB
Python (python3)
时间限制
1400 ms
内存限制
512 MB
其他编译器
时间限制
1000 ms
内存限制
256 MB
栈限制
131072 KB
思路:就是先求有几个环(注意不是普通的环,而是题目给的章鱼环,也就是一个环里面的所有顶点只能参与组成一个环。然后如果只有一个环的话,再dfs求这个环的长度
ps:这个代码是凳子学长写的,我的只得了15分,超时了
#include <bits/stdc++.h> using namespace std; #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); const int N=1e5+5; vector<int> edge[N]; bool flag[N],visited[N]; int res1,res2,node; // 用于求有几个环 void dfs(int s,int last) { visited[s]=true; flag[s]=true; // flag数组用于标记当前次dfs的结点 for(int i=0;i<edge[s].size();i++) { int nx=edge[s][i]; // last表示当前节点的上一个节点,因为是无向图 // 所以不能又遍历回去了,所以nx即下一个节点不能是last if(nx!=last) { if(flag[nx]) { // 如果下一个节点访问过了,说明成环了,则res2++ res2++; node=nx; // 并保留成环节点,用于求出环的节点个数 } else { dfs(nx,s); } } } } // 求环有几个节点 int dfs(int s,int last,int cnt) { flag[s]=true; for(int i=0;i<edge[s].size();i++) { int nx=edge[s][i]; if(nx!=last) { if(flag[nx]) { // 如果访问过了,说明成环了,返回节点个数 return cnt; } else { int res=dfs(nx,s,cnt+1); if(res!=0) return res; } } } flag[s]=false; return 0; } void solve() { for(int i=0;i<N;i++) edge[i].clear(),visited[i]=false; int n,m,from,to; cin>>n>>m; for(int i=1;i<=m;i++) { cin>>from>>to; edge[from].push_back(to); edge[to].push_back(from); } int cnt=0; for(int i=1;i<=n;i++) { res2=0,memset(flag,0,sizeof(flag)); if(visited[i]==false) { // visited的存在就是有样例三那种情况 dfs(i,0); res2/=2; // 由于在回溯的过程中,每个环都会被重复判断一次,画个图就好理解了,所以需要/=2 if(res2==1) { // 如果只有一个环,说明是一个章鱼图,则cnt++ cnt++; } } } if(cnt==1) { // 如果只有一个章鱼图 memset(flag,0,sizeof(flag)); res1=dfs(node,0,1); // 求环节点个数 cout<<"Yes"<<" "<<res1<<endl; } else cout<<"No"<<" "<<cnt<<endl; } int main() { IOS; int T=1; cin>>T; while(T--) { solve(); } return 0; }
上面那个是学长写的
下面这个是我写的
#include "bits/stdc++.h" using namespace std; const int N = 1e5 + 10; vector<int> v[N]; int vis[N]; int res; vector<int> path; vector<vector<int> > finalResult; map<int, int> mp; bool isSame(vector<int> x, vector<int> y){ if(x.size() != y.size()) return false; else { sort(x.begin(),x.end()); sort(y.begin(),y.end()); return x == y; } } bool isExist(vector<int> x){ for(int i = 0; i < finalResult.size(); i ++){ if(isSame(finalResult[i], x)) return true; } return false; } void dfs(int x, int t){ if(x == t){ path.push_back(x); if(path.size() > 2 && !isExist(path)){ mp[x] ++; finalResult.push_back(path); } path.pop_back(); vis[x] = 0; return; } vis[x] = 1; path.push_back(x); for(int i = 0; i < v[x].size(); i ++){ int xx = v[x][i]; if(!vis[xx]) dfs(xx, t); } vis[x] = 0; path.pop_back(); } int main(){ ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int T; cin>>T; int a, b; int n, m; while(T--){ cin>>n>>m; mp.clear(); finalResult.clear(); for(int i = 1; i <= n; i ++){ v[i].clear(); } for(int i = 0; i < m; i ++){ cin>>a>>b; v[a].push_back(b); v[b].push_back(a); } for(int i = 1; i <= n; i ++){ for(int j = 0; j < v[i].size(); j ++){ dfs(v[i][j], i); } } if(finalResult.size() == 1) { res = finalResult[0].size(); cout<<"Yes"<<" "<<res; } else { int anss = 0; // for(int i = 0; i < finalResult.size(); i ++){ // mp[finalResult[i][finalResult[i].size() - 1]] ++; // } for(auto x : mp){ if(x.second == 1) anss ++; } cout<<"No"<<" "<<anss; } if(T != 0) cout<<endl; } return 0; }
RC-u5 工作安排
分数 30
全屏浏览
切换布局
作者 DAI, Longao
单位 杭州百腾教育科技有限公司
小 K 有 N 项工作等待完成,第 i 项工作需要花 ti 单位时间,必须在 di 时刻或之前完成,报酬为 pi。假设小 K 工作时刻从 0 开始,且同一时刻只能做一项工作、工作一旦开始则不可中断或切换至其他工作,请你帮小 K 规划一下如何选择合适的工作,使小 K 可以获得最多的报酬。
输入格式:
输入第一行是一个正整数 T (≤5),表示数据的组数。
接下来有 T 组数据,每组数据第一行是一个正整数 N (≤5000),表示待完成工作的数量。接下来的 N 行,每行三个非负整数 ti、di、pi (均 ≤5000;1≤i≤N),表示第 i 项工作需要花费的时间、截止时间以及报酬。
输出格式:
对于每组数据,输出小 K 能获得最多的报酬是多少。
输入样例:
3 5 1 2 50 3 3 100 1 5 1 3 2 5000 4 5 30 5 1 2 50 3 3 20 1 5 1 3 2 5000 4 5 30 5 1 2 50 3 3 100 1 5 1 3 2 5000 5 5 800
输出样例:
101 80 800
代码长度限制
16 KB
Java (javac)
时间限制
1000 ms
内存限制
256 MB
其他编译器
时间限制
400 ms
内存限制
64 MB
栈限制
8192 KB
思路:其实就是一个01背包,但是附加了时间的限制,这样的话我们按照时间进行排序,然后在进行dp就可以了 ,如果不加时间限制的话,如果是先遍历时间上靠后完成的任务,然后再遍历靠前的任务,那么靠前的任务的收益就加不上了,因为你后面那个不能再重来一遍了,其实就相当于你靠前的那个任务没做一样了。
#include "bits/stdc++.h" using namespace std; const int N = 5100; int t[N], d[N], p[N]; typedef long long ll; ll dp[N]; ll ans = 0, tt; int k = 0; struct node{ int t; int d; int p; bool operator < (const node & b)const { if(b.d != d) return d < b.d; else return p > b.p; } }; node a[N]; void f(int n){ for(int i = 0; i < n; i ++){ for(int j = a[i].d; j >= a[i].t; j --){ dp[j] = max(dp[j], dp[j - a[i].t] + a[i].p); if(dp[j] > ans){ ans = dp[j]; } } } } int main(){ int T; cin>>T; while(T--){ ll n , aa, b, c; ans = 0, tt = 0; cin>>n; memset(t, 0, sizeof(t)); memset(d, 0, sizeof(d)); memset(p, 0, sizeof(p)); memset(dp, 0, sizeof(dp)); k = 0; for(int i = 0; i < n; i++){ cin>>aa>>b>>c; if(aa <= b) a[k].t = aa, a[k].d = b, a[k ++ ].p = c, tt = max(tt, b); } sort(a, a + k); f(k); cout<<ans; if(T != 0) cout<<endl; } return 0; }