简单记录一下牛客华为刷题C++,以下为个人刷题思路,仅供参考,代码亲测可通过。
11.数字颠倒
使用C++自带的函数,to_string 将整型转换成字符串类型,reverse()函数反转string
reverse(s.begin(), s.end());
reverse(a,a+10);反转字符数组,第二个参数是反转字符串的下一个地址,也就是a反转后只能得到9个字符。
#include <iostream>
#include<algorithm>
#include<string>
using namespace std;
int main() {
int num;
cin >> num;
string s = to_string(num);
reverse(s.begin(),s.end());
cout <<s<<endl;
}
12.字符串反转
字符串计算长度可以使用strlen()、sizeof()、length()
strlen():求出的不包含结束符'\0',遇到'\0'结束
sizeof():求出长度包括结束符'\0'
length():求出的不包含结束符'\0',遇到'\0'结束
统计字符数组:
char ch1[ ] = {'1', '2', '\0', 'e'};
结果:strlen --> 2
sizeof--> 4
统计字符串数组:char str2[] = { "12\0e"};
结果:strlen --> 2 (无\0,遇到\0结束)
sizeof--> 5 (有\0)
注意:C/C++的strlen(str)和str.length()和str.size()都可以求字符串长度。其中str.length()和str.size()是用于求string类对象的成员函数,strlen(str)是用于求字符数组的长度,其参数是char*。
#include <iostream>
#include<algorithm>
#include<string>
using namespace std;
int main() {
string str;
cin >> str;
int len =str.length();//实际大小
for (int i = 0; i < len; i++)
{
while (str[i] < 97 || str[i] > 122) //范围不在a-z
{
cout << "请输入小写字符串" << endl;
return -1;
}
}
//符合条件 翻转
reverse(str.begin(), str.end());
cout << str << endl;
}
13.句子逆序
思路:使用vector容器,每输入一个单词就放进容器,当输入换行符,则停止输入。反向输出容器内容。
#include <iostream>
#include <iostream>
#include<vector>
using namespace std;
int main() {
string s;
vector<string> v;
while (cin >> s )
{
v.push_back(s);
if (getchar() == '\n')
{
break;
}
}
for (int i = v.size()-1; i >=0; i--)
{
cout << v[i]<< ' ';
}
}
14.字符串排序
1、使用vector容器存储输入的字符串
2、sort()函数,仅排序全是大写或全是小写的字符串,按照ASCII排序
#include <iostream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
void sort_string(int num)
{
string str;
vector<string > v;
for (int i = 0; i < num; i++)
{
cin >> str;
v.push_back(str);
}
sort(v.begin(), v.end());
for (int i = 0; i < num; i++)
{
cout << v[i] << endl;
}
}
int main() {
int num;
while (cin >> num)
{
sort_string(num);
}
}
15.求int型正整数在内存中存储1的个数
bitset 用于字符串和整数转换,这个序列被当做最低索引元素位于右侧,因此可以用来转换二进制。
定义:构造很多 bitset<N> b;
操作接口:
#include <iostream>
#include<bitset>
using namespace std;
int main()
{
int num;
while(cin >> num)
{
bitset<32> b(num) ;
cout << b.count();
}
return 0;
}
16、购物单
难度较大,参考了大神的代码,加入自己的理解,如下:
在0-1背包模型中加入了限制条件:购买附件必须要购买主件,每个主件有0~2个附件
每个主件有四种情况,主件,主件+附件1,主件+附件2,主件+附件1+附件2
背包中设置两层循环,第一层循环是商品种类,第二层循环是钱金额。当金额为1、2、3.....、N的时候,去购买物品,当金额足够时就去购买。
如果总金额能够覆盖该商品,那么取前i-1个商品的满意度最大累计和,进行比较。因此得到:
dp[i][j] = j >= a ? max(dp[i-1][j-a]+b,dp[i - 1][j]) : dp[i - 1][j];
#include <iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int N = 0;
int m = 0; //N是总钱数, m是物品数量
cin >> N >> m;
N /= 10;
vector<vector<int>> prices(61, vector<int>(3, 0)); //价格;最多方60个物品,每个物品三种情况
vector<vector<int>> priceMultiplyPriority(61, vector<int>(3, 0));//满意度
for (int i = 1; i <= m; i++)
{
int a, b, c;
cin >> a >> b >> c;
a /= 10;
b *= a;
if (c == 0) //说明是主件
{
prices[i][0] = a;
priceMultiplyPriority[i][0] = b;
}
else //说明该物品是附件
{
if (prices[c][1] == 0)//附件1
{
prices[c][1] = a;
priceMultiplyPriority[c][1] = b;
}
else//附件2
{
prices[c][2] = a;
priceMultiplyPriority[c][1] = b;
}
}
}
//使用背包
vector<vector<int>> dp(m + 1, vector<int>(N + 1, 0));
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= N ; j++)
{
int a = prices[i][0];
int b = priceMultiplyPriority[i][0];
int c = prices[i][1];
int d = priceMultiplyPriority[i][1];
int e = prices[i][2];
int f = priceMultiplyPriority[i][2];
dp[i][j] = j >= a ? max(dp[i-1][j-a]+b,dp[i - 1][j]) : dp[i - 1][j];
dp[i][j] = j >= (a + c) ? max(dp[i - 1][j - a - c] + b + d, dp[i][j]) : dp[i][j];
dp[i][j] = j >= (a + e) ? max(dp[i - 1][j - a - e] + b + f, dp[i][j]) : dp[i][j];
dp[i][j] = j >= (a + c+ e) ? max(dp[i - 1][j - a -c- e] + b + d + f, dp[i][j]) : dp[i][j];
}
}
cout << dp[m][N] * 10 << endl;
return 0;
}
17、坐标移动
思路:
1、将输入的字符长串,根据;进行分割,并存入vector容器
2、对容器内成员判断是否为有效字符串
3、坐标移动
#include <iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<cstring>
#include<sstream>
using namespace std;
//判断是否为有效字符
bool isTrue(string s)
{
int Numlen = 0;
if (s.length() == 1) return false;
if (s[0] == 'A' || s[0] == 'D' || s[0] == 'W' || s[0] == 'S')//第一个单词符合
{
for (int i = 1; i <= s.length() - 1; i++)
{
if (s[i] >= '0' && s[i] <= '9')
{
Numlen++;
}
else
{
return false;
}
}
if (Numlen == s.length() - 1)
{
return true;
}
else
return false;
}
else
return false;
}
//判断走向函数
void Go(int& x, int& y,string s)
{
//数字和字母分割
int n = stoi(s.substr(1, s.length() - 1));
switch (s[0])
{
case 'A': x -= n; break;
case 'W': y += n; break;
case 'D': x += n; break;
case 'S': y -= n; break;
default: cout << "走向有误" << endl;
}
}
int main()
{
string str;
vector<string> v; //用于存储
int len = 0;
int x = 0, y = 0; //初始坐标归零
while (cin >> str)
{
//1、先将字符串按照;进行分割
for (int i = 0; i < str.length(); i++)
{
while (str[i] != ';')
{
len++;
i++;
}
v.push_back(str.substr(i - len,len));
len = 0;
}
//2、判断是否为有效字符串
for (int i = 0; i < v.size(); i++)
{
if(isTrue(v[i])== 0)//字符无效
{
v.erase(v.begin() + i );
i--;
}
}
//输出有效的字符
vector<string>::iterator it;
/*for (it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}*/
for (it = v.begin(); it != v.end(); it++)
{
Go(x, y, *it);
}
cout << x << ',' << y << endl;
}
return 0;
}