CSP-J2019试题题解
1.数字游戏
原题:
https://www.luogu.com.cn/problem/P5660
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; string s; int main(){ cin>>s; int num=0; for ( int i=0;i<s.length();i++) if (s[i]== '1' )num++; cout<<num; return 0; } |
解题思路:
最简单的方法,把数字变成一个字符串,遍历字符串,统计1的个数
2.公交换乘
原题:https://www.luogu.com.cn/problem/P5661
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include<bits/stdc++.h> using namespace std; const int N = 1e5+255; int n,pri[N],t[N],ans=0,fp=1; bool flag[N]; int main(){ cin>>n; for ( int i=1;i<=n;i++){ cin>>flag[i]>>pri[i]>>t[i]; if (flag[i]==0)ans+=pri[i]; else { bool ok=0; while (t[i]-t[fp]>45)fp++; for ( int j=fp;j<i;j++){ if (!flag[j]&&pri[j]>=pri[i]){ ok=1; flag[j]=1; break ; } } if (!ok)ans+=pri[i]; } } cout<<ans; return 0; } |
解题思路:
这题暴力解法只能得45分,其实可以设一个指针,指向每一次花费,遍历时间,如果时间差大于45分钟,指针指向下一个,累加花费就可以了
3.纪念品
原题:https://www.luogu.com.cn/problem/P5662
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include<bits/stdc++.h> using namespace std; const int N = 1e6+255; int T,n,m,dp[N],p[1005][1005]; int main(){ cin>>T>>n>>m; for ( int i=1;i<=T;i++){ for ( int j=1;j<=n;j++){ cin>>p[i][j]; } } for ( int k=1;k<=T;k++){ memset (dp,0, sizeof (dp)); for ( int i=1;i<=n;i++){ for ( int j=p[k][i];j<=m;j++){ dp[j]=max(dp[j],dp[j-p[k][i]]+p[k+1][i]-p[k][i]); } } m+=dp[m]; } cout<<m; return 0; } |
解题思路:
这道题是完全背包的模版题,每次累加最大价值即可
4.加工零件
原题:https://www.luogu.com.cn/problem/P5663
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #include<bits/stdc++.h> using namespace std; const int N = 1e5+255; struct edg{ int to,next; }e[4*N]; int n,m,q,a,l,head[N],cnt=-1,dis[N][2]; bool vis[N][2]; void add( int x, int y){ e[++cnt]=(edg){y,head[x]}; head[x]=cnt; } void bfs(){ queue< int >q;q.push(1);vis[1][0]=1; while (q.size()){ int t=q.front();q.pop(); for ( int i=head[t];~i;i=e[i].next){ int v=e[i].to; if (dis[t][1]+1<dis[v][0]){ dis[v][0]=dis[t][1]+1; if (!vis[v][0]){ vis[v][0]=1; q.push(v); } } if (dis[t][0]+1<dis[v][1]){ dis[v][1]=dis[t][0]+1; if (!vis[v][1]){ vis[v][1]=1; q.push(v); } } } } } int main(){ memset (dis,0x7f, sizeof (dis)); memset (head,-1, sizeof (head)); cin>>n>>m>>q; for ( int i=1,x,y;i<=m;i++){ cin>>x>>y; add(x,y); add(y,x); } dis[1][0]=0; bfs(); while (q--){ cin>>a>>l; if (l%2==0)cout<<(l>=dis[a][0]? "Yes\n" : "No\n" ); else cout<<(l>=dis[a][1]? "Yes\n" : "No\n" ); } return 0; } |
解题思路:
有的人可能看到题就写了一个深搜,但是数据一大就会超时,所以就要用到奇偶最短路,求出最短路以此判断输出即可
注意事项:
1.由于是求奇偶最短路,所以有两条路径,那vis数组也应该有两个
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通