牛客春招刷题训练营 - 3.18题解 | C++
活动地址: 牛客春招刷题训练营 - 编程打卡活动
简单题:求int型正整数在内存中存储时1的个数
一种做法是直接模拟进制转换
#include <iostream> using namespace std; int main() { int n; cin >> n; int cnt = 0; while(n) { cnt += (n % 2); n /= 2; } cout << cnt << endl; return 0; }
另一种做法是直接调用C++的内置函数__builtin_popcount。
#include <iostream> using namespace std; int main() { int n; cin >> n; cout << __builtin_popcount(n) << endl; return 0; }
中等题:整数与IP地址间的转换
和简单题一样,其实本质就是一个进制转换题,只不过这题是256进制(因为每一位是0~255)。
第一问是256进制转10进制,用字符串读入处理一下就行。
第二问是10进制转256进制,需要注意的是256^4-1的值超过了int范围,所以需要用long long来存。
#include <algorithm> #include <iostream> #include <vector> using namespace std; using ll = long long; int main() { string s; ll n; cin >> s >> n; ll t = 0, res = 0; for(auto c: s) { if(c == '.') { res = res * 256 + t; t = 0; } else { t = t * 10 + c - '0'; } } res = res * 256 + t; vector<int> ip; while(n) { ip.push_back(n % 256); n /= 256; } cout << res << endl; while(!ip.empty()) { cout << ip.back(); ip.pop_back(); if(ip.size() != 0) cout << "."; } return 0; }
困难题:字符串通配符
这道题是前一天的困难题(计算字符串的编辑距离)的加强版吧。
其实本质思想是一模一样的。为什么这么说呢?
因为“可以匹配得到”是不是也可以看作是编辑距离为0。
所以这道题就是有通配符的字符串编辑距离计算。
实际写起来细节比较多,不过仔细分类讨论一下就行了。
#include <iostream> #include <vector> using namespace std; int main() { string s, p; cin >> s >> p; int ls = s.size(), lp = p.size(); vector<vector<int>> dp(ls+1, vector<int>(lp+1)); for(int i=0; i<=ls; i++) { if(i >= 1 && s[i-1] == '*') { dp[i][0] = dp[i-1][0]; } else { if(i >= 1) dp[i][0] = dp[i-1][0] + 1; else dp[i][0] = 0; } } for(int j=0; j<=lp; j++) dp[0][j] = j; auto check = [&](char x) { if(x >= '0' && x <= '9') return 1; if(x >= 'A' && x <= 'Z') return 2; if(x >= 'a' && x <= 'z') return 3; return 0; }; for(int i=1; i<=ls; i++) { for(int j=1; j<=lp; j++) { if(s[i-1] == p[j-1]) dp[i][j] = dp[i-1][j-1]; else { if(check(s[i-1]) + check(p[i-1]) == 5 && abs(s[i-1]-p[j-1]) == 32) { dp[i][j] = dp[i-1][j-1]; } else if(check(s[i-1])) { dp[i][j] = 1; } else if(check(p[j-1])) { if(s[i-1] == '*') { dp[i][j] = min(dp[i-1][j], dp[i][j-1]); dp[i][j] = min(dp[i][j], dp[i-1][j-1]); } else if(s[i-1] == '?') { dp[i][j] = dp[i-1][j-1]; } } else { dp[i][j] = 1; } } } } if(dp[ls][lp] == 0) cout << "true" << endl; else cout << "false" << endl; return 0; }#牛客春招刷题训练营#