第三次实验

开个帖跟着小朋友每周写题顺便记录一下一些容易错的地方。

A-D是基础语法,E为01背包,F复杂一点的01背包,G多重背包

问题 A: 零基础学C/C++147——统计每个字母个数

题目描述:输入一段英文(字数小于100),以回车结束,统计其中的每个字母出现次数,不区分大小字。

输入:多组测试数据,每组输入一段英文(字数小于100),以回车结束

输出:输出每个字母出现的次数(次数为零的不输出) 每组数据后面输出一个空行

样例输入:Welcome to c world.

样例输出

c: 2
d: 1
e: 2
l: 2
m: 1
o: 3
r: 1
t: 1
w: 2

这道题问题一般出现在输入问题,带空格的整行字符串

一、cin.getline()
用法:接收一个字符串,可以接收空格并输出

#include <iostream>
using namespace std;
main ()
{
char m[20];
cin.getline(m,5);
cout<<m<<endl;
}

/*
输入:jkljkljkl
输出:jklj


接收5个字符到m中,其中最后一个为'',所以只看到4个字符输出;


如果把5改成20:
输入:jkljkljkl
输出:jkljkljkl


输入:jklf fjlsjf fjsdklf
输出:jklf fjlsjf fjsdklf
*/
cin.getline()示例

延伸:
1、cin.getline()实际上有三个参数,cin.getline(接收字符串的变量,接收字符个数,结束字符)
2、当第三个参数省略时,系统默认为''
3、如果将例子中cin.getline()改为cin.getline(m,5,'a');当输入jlkjkljkl时输出jklj,输入jkaljkljkl时,输出jk


二、getline()
用法:接收一个字符串,可以接收空格并输出,需包含“#include<string>”

#include<iostream>
#include<string>
using namespace std;
main ()
{
string str;
getline(cin,str);
cout<<str<<endl;
}

/*
输入:jkljkljkl
输出:jkljkljkl


输入:jkl jfksldfj jklsjfl
输出:jkl jfksldfj jklsjfl

*/
getline()示例

注意的问题
1、cin.getline()属于istream流,而getline()属于string流,是不一样的两个函数
2、当同时使用cin>>,getline()时,需要注意的是,在cin>>输入流完成之后,getline()之前,需要通过
方法一:str=" "; getline(cin,str);

这一段使用的是CSDN博主「左庶长」的原创文章
原文链接:C++:cin、cin.getline()、getline()的用法 作者 左庶长

/*代码1*/
#include<bits/stdc++.h>
using namespace std;

int main(){

    string t;
    int len = 0,ans[30];
    while(getline(cin,t)){
        memset(ans,0,sizeof(ans));
        len = t.size();
        for(int i = 0;i < len;++i){
            if(t[i]>='A'&&t[i]<='Z'){
                ans[t[i]-'A']++;
            }
            if(t[i]>='a'&&t[i]<='z'){
                ans[t[i]-'a']++;
            }
        }
        for(int i = 0;i < 26;++i){
            if(ans[i])cout<<char(i+'a')<<": "<<ans[i]<<endl;
        }
        cout<<endl;
    }
    return 0;
}
/*代码2(用的小朋友的)*/
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int main()
{
    char str[110];
    int l[26];
    int i;
    while (cin.getline(str, 110))
    {    
        for (i = 0; i < 26; i++){l[i] = 0;}
        
        for (i = 0; i < strlen(str); i++)
        {
            if (str[i] >= 'A' && str[i] <= 'Z')
            {
                l[str[i] - 'A'] ++;
            }
            if (str[i] >= 'a' && str[i] <= 'z')
            {
                l[str[i] - 'a'] ++;
            }
        }
        for (i = 0; i < 26; i++)
        {
            if (l[i] > 0)
            {
                printf("%c: %d
", i + 'a', l[i]);
            }
        }
        printf("
");
    }
}
ac代码

问题 B: 零基础学C/C++148——字符串整理

题目描述: 输入一个字符串,将字符串中所有非英文字母的字符删除后输出。

输入:多组测试数据,每组输入一个以回车结束的字符串。

输出:将这行字符中所有非英文字母的字符删除后输出

样例输入

I Have 2 MP3.
please you declare the variable m_n_DLength10!

样例输出 

IHaveMP
pleaseyoudeclarethevariablemnDLength

这题要注意的地方和A题一样
#include<bits/stdc++.h>
using namespace std;

int main(){
    string t;
    int len = 0;
    while(getline(cin,t)){
        len = t.size();
        for(int i=0;i<len;++i){
            if(t[i]>='a'&&t[i]<='z'||t[i]>='A'&&t[i]<='Z')
                cout<<t[i];
        }
        cout<<endl;
    }
    return 0;
}
ac代码

 

问题 C: 零基础学C/C++149——重组字符串

题目描述:输入一个以回车结束的字符串,将字符串中的字符按ASCII码从小到大顺序重组后输出。

输入:输入为多组测试数据。输入一个以回车结束的字符串(少于80个字符)。

输出:将字符串中的字符按ASCII码从小到大顺序重组后输出

样例输入:Student

样例输出:Sdenttu

简单排序问题,了解ASCII码和sort或其他排序的使用就好了

#include<bits/stdc++.h>
using namespace std;

int main(){
    char t[100];
    int len = 0;
    while(cin.getline(t,100)){
        len = strlen(t);
        sort(t,t+len);
        for(int i = 0;i < len;++i)cout<<t[i];
        cout<<endl;
    }
    return 0;
}
ac代码

问题 D: 零基础学C/C++150——统计元音字母数

题目描述:输入一行字符串,统计字符串中所有英文字母中的各元音字母'a/A'、'e/E'、'i/I'、'o/O'、'u/U'的个数

输入:输入为多组测试数据。输入一行字符串(少于80个字符),以回车结束。

输出:逐行输出字符串中各元音字母'a/A'、'e/E'、'i/I'、'o/O'、'u/U'的个数。

样例输入 :There are 10 ducks.

样例输出 

1
3
0
0
1
#include<bits/stdc++.h>
using namespace std;

int main(){
    char t[100];
    int len = 0;
    int a,e,i,o,u;
    while(cin.getline(t,100)){
        a=e=i=o=u=0;
        len = strlen(t);
        for(int i=0;i<len;++i){
            if(t[i]=='a'||t[i]=='A')a++;
            if(t[i]=='e'||t[i]=='E')e++;
            if(t[i]=='i'||t[i]=='I')i++;
            if(t[i]=='o'||t[i]=='O')o++;
            if(t[i]=='u'||t[i]=='U')u++;
        }
        cout<<a<<endl<<e<<endl<<i<<endl<<o<<endl<<u<<endl;
    }
    return 0;
}
ac代码
 

问题 E: 深入浅出学算法073-开心的金明

题目描述:提供总钱数N和需要购买的物品总数m,每个物品都有重要度p,价格v,求在不超过N的情况下购买物品价格v*重要度p的最大值

输入:第一行,为2个正整数,用一个空格隔开:N m(其中N(<30000)表示总钱数,m(<25)为希望购买物品的个数。)

   从第2行到第m+1行,第jj行给出了编号为j-1的物品的基本数据,每行有2个非负整数vp(其中v表示该物品的价格(v10000),p表示该物品的重要度(15)

输出:1个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值(<100000000)。

样例输入 

1000 5
800 2
400 5
300 5
400 3
200 2

样例输出 3900

01背包问题

#include<bits/stdc++.h>
using namespace std;


int main(){
    int N,m,v[50],p[50];
    int dp[30100];
    memset(dp,0,sizeof(dp));
    cin>>N>>m;
    for(int i=0;i<m;++i){
        cin>>v[i]>>p[i];
    }
    for(int i=0;i<=m;++i){
        for(int k=N;k>=v[i];k--){
            dp[k]=max(dp[k],dp[k-v[i]]+v[i]*p[i]);
        }
    }
    cout<<dp[N]<<endl;
    return 0;
}
ac代码

问题 F: 深入浅出学算法076-金明的预算方案

 

题目描述:比上一题多了一个属性q,q表示该物品是主件还是附件。主件的q是0,附件的q是主件编号。一个主件最多对应两个附件。金明可以购买主件,但是没有买主件就不能买这个主件对应的附件。

提供总钱数N和需要购买的物品总数m,每个物品都有重要度p,价格v,求在不超过N的情况下购买物品价格v*重要度p的最大值

输入:第1行,为两个正整数,用一个空格隔开:

N m(其中N(<32000)表示总钱数,m(<60)为希望购买物品的个数。) 从第2行到第m+1行,第j行给出了编号为j-1的物品的基本数据,每行有3个非负整数

vpq (其中v表示该物品的价格(v<10000),p表示该物品的重要度(1-5),q表示该物品是主件还是附件。如果q=0,表示该物品为主件,如果q>0,表示该物品为附件,q是所属主件的编号)

输出:一个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值(<200000)。

样例输入

1000 5
800 2 0
400 5 1
300 5 1
400 3 0
500 2 0

样例输出 

2200
#include<bits/stdc++.h>
using namespace std;

int main(){
    int N,m,v[100],q[100],p[100];
    int fp[100][5],dp[32100];
    int v1,v2,p1,p2;
    memset(fp,0,sizeof(fp));
    memset(dp,0,sizeof(dp));
    cin>>N>>m;//N/=10;
    for(int i=1;i<=m;++i){
        cin>>v[i]>>p[i]>>q[i];//p[i]/=10;
        if(q[i]){
            if(fp[q[i]][1])    fp[q[i]][2]=i;
            else fp[q[i]][1]=i;
        }
    }
    for(int i=1;i<=m;++i){
        if(q[i]==0){
            v1=v[fp[i][1]],p1=p[fp[i][1]];
            v2=v[fp[i][2]],p2=p[fp[i][2]];
            for(int k=N;k>=v[i];k--){
                dp[k]=max(dp[k],dp[k-v[i]]+v[i]*p[i]);
                if(v1&&k>=v[i]+v1){
                    dp[k]=max(dp[k],dp[k-v[i]-v1]+v[i]*p[i]+v1*p1);
                }
                if(v2&&k>=v[i]+v2){
                    dp[k]=max(dp[k],dp[k-v[i]-v2]+v[i]*p[i]+v2*p2);
                }
                if(v1&&v2&&k>=v[i]+v1+v2){
                    dp[k]=max(dp[k],dp[k-v[i]-v1-v2]+v[i]*p[i]+v1*p1+v2*p2);
                }
            }
        }
    }
    cout<<dp[N]<<endl;
    return 0;
}
/*for(int i=0;i<=m;++i){
        for(int k=N;k>=v[i];k--){
            dp[k]=max(dp[k],dp[k-v[i]]+v[i]*p[i]);
        }
    }
*/
ac代码

问题 G: 多重背包

题目描述:有一个体积为V的背包,有m种物品,每种物品有体积和价值,且数量一定。求背包能装下的最大价值

输入:第一行两个整数V和m。接下来m行,每行3个整数,表示第i种物品的数量、体积和价值。V<=104,m<=500 ,个数、体积、价值不超过1000

输出:输出一个整数,表示背包能装下的最大价值

样例输入

10 4
2 3 2
2 4 3
1 2 2
4 5 3

样例输出:8

二进制

#include<bits/stdc++.h>
using namespace std;
int v[10005],w[10005];
int dp[10005];
  
int main(){
    int all,m,k=0;
    cin>>all>>m;
    for(int i=0;i<m;i++){
        int a,b,n;
        cin>>n>>a>>b;
        int cnt=1;
        while(n>0){
            if(n>=cnt){
                w[k]=cnt*a;
                v[k++]=cnt*b;
            }else{
                w[k]=n*a;
                v[k++]=n*b;
            }
            n-=cnt;
            cnt*=2;
        }
    }
    for(int i=0;i<k;i++){
        for(int j=all;j>=w[i];j--){
            dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
        }
    }
    cout << dp[all] <<endl;
}
ac代码
参考:https://www.nowcoder.com/questionTerminal/6ce78d70a25347058004691035d7540b
原文地址:https://www.cnblogs.com/h404nofound/p/14640923.html