开个帖跟着小朋友每周写题顺便记录一下一些容易错的地方。
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 */
延伸:
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 */
注意的问题
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(" "); } }
问题 B: 零基础学C/C++148——字符串整理
题目描述: 输入一个字符串,将字符串中所有非英文字母的字符删除后输出。
输入:多组测试数据,每组输入一个以回车结束的字符串。
输出:将这行字符中所有非英文字母的字符删除后输出
样例输入
I Have 2 MP3.
please you declare the variable m_n_DLength10!
#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; }
问题 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; }
问题 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; }
问题 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表示该物品的价格(v≤10000),p表示该物品的重要度(1−5)
输出:1个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值(<100000000)。
样例输出 :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; }
问题 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]); } } */
问题 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; }
参考:https://www.nowcoder.com/questionTerminal/6ce78d70a25347058004691035d7540b