牛客华为刷题笔记(三)

简单记录一下牛客华为刷题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;
}

  • 29
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值