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数组也应该有两个

posted @   天雷小兔  阅读(58)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示