华为机试复习

1. 杂乱知识点

判断x是否为素数(质数)

bool is_prime(int x) {
	for (int i=2; i<=sqrt(x); i++)
		if (x%i == 0) return false;
	return true;
}

栈的使用方法

stack<int> s;
int 5;
s.push(5);
bool b = (s.size() != 0);
int y = s.top();
if (b == true) s.pop();

排列组合的使用方法

vector<int> v;
sort(v.begin(),v.end());
do {
	// do something
} while (next_permutation(v.begin(), v.end()));

走方格的方案数(棋盘n乘m)

// n+m choose m = (n+m)*(n+m-1)*...*(n+1)/m!
int f(int n, int m) {
	int a=1, b=1;
	for (int i=1; i<=m; i++) {
		a *= n+i;
		b *= i;
	}
	return a/b;
}

vectorinsert | set的使用方法

vector<int> v1, v2;
v1.insert(v1.end(), v2.begin(), v2.end());
set<int> s(v1.begin(), v1.end()); // set将会帮你把这个数组按升序排好序

unordered_set去重复

unordered_set<char> set;
char c;
if (set.count(c)!=1)
	set.insert(c);

按照value的降序给map排序,如果value相同,按照key升序排序

bool cmp(pair<char, int> a, pair<char, int> b) {
	if (a.second == b.second) return (a.first < b.first);
	return (a.second > b.second);
}
int main() {
	string s;
	cin >> s;
	map<char, int> m;
	for (char c: s) m[c]++;
	vector<pair<char, int>> v(m.begin(), m.end());
	sort(v.begin(), v.end(), cmp);
	for (auto i : v) cout << i.first;
	cout << endl;
}

内置单向链表

forward_list<int> list;
int x = 10;
// it将指向forward_list中value为10的ListNode
auto it = find(list.begin(), list.end(), x); 
int y = 20;
list.insert_after(it, y);
int k = 4;
// 把value为4的ListNode从链表中删除
list.remove(k);

二分搜索

// 107求解立方根
double f(double x) {
	double l = 0.0;
	double r = max(1.0, x);
	double k; // mid-point
	while (r-l>0.001) {
		k = (r+l)/2;
		if (k*k*k>x) r=k;
		else l=k;
	}
	return k;
}

中间扩张法找最长回文子串的长度

int f(string s, int l, int r) {
	while (l>=0 && r<s.length() && s[r]==s[l]) {
		l--;
		r++;
	}
	return r-l+1-2;
}
int main() {
	string s;
	int ans = 0;
	int x1, x2;
	cin >> s;
	for (int i=0; i<=s.length(); i++) {
		x1 = f(s, i, i);
		x2 = f(s, i, i+1);
		ans = max(max(x1, x2), ans);
	}
	cout << ans << endl;
	return 0;
}

因数分解

void print_prime(int n) {
	while (n%2==0) {
		cout << 2 << " ";
		n /= 2;
	}
	for (int i=3; i<=sqrt(n); i+=2) {
		while (n%i==0) {
			cout << i << " ";
			n /= i;
		}
	}
	if (n>2) cout << n;
	cout << endl;
}

map的使用方法

map<int, int> m;
map<int, int>::iterator it;
int a;
it = m.find(a);
if (it != m.end()) m[a] = it->second + b;
else m[a] = b;

bitset的使用方法

int x;
bitset<32> b(x); // 二进制的x

HJ31单词倒排 | cin.get(c)

int main() {
	char c;
	string ans = "";
	string word = "";
	while (cin.get(c)) {
		if (isalpha(c)) word += c;
		else {
			if (word != "") {
				if (ans != "") ans = word+' '+ans;
				else ans = word;
				word.clear();
			}
		}
	}
}

struct的使用方法

struct ListNode {
	int key;
	ListNode* next;
};
int main() {
	ListNode* head = new ListNode();
	return 0;
}

2. 动态规划

最长递增子序列

// 24合唱队
// 103求解最长递增子序列的长度
int n;
vector<int> v;
for (int i=0; i<n; i++) {
	int temp;
	cin >> temp;
	v.push_back(temp);
}
// 1. 定义dp[i]为以v[i]结尾的最长递增子序列的长度
vector<int> dp(n, 0);
for (int i=0; i<n; i++) {
	dp[i] = 1; // 2. 初始化dp数组
	for (int j=0; j<i; j++) {
		if (v[i] > v[j]) // 3. 状态转移方程
			dp[i] = max(dp[i], dp[j]+1);
	}
}
// 4. 求解
cout << *max_element(dp.begin(), dp.end()) << endl;

把m个同样的苹果放在n个同样的盒子里

// 61放苹果
// 1. 定义dp[i][j]为把i个苹果放到j个盒子里面的放法种数
int dp[11][11];
int f(int m, int n) {
	// 2. 初始化二维数组
	for (int i=0; i<11; i++) {
		dp[0][i] = 1;
		dp[i][1] = 1;
		dp[1][i] = 1;
		dp[i][0] = 1;
	}
	// 3. 状态转移方程
	for (int i=2; i<11; i++) {
		for (int j=2; j<11; j++) {
			// 如果盒子有富裕,则和盒子正好的情况一样
			if (j>i) dp[i][j] = dp[i][i]; 
			// 情况1:至少有一个盒子是空的dp[i][j] = dp[i][j-1]
			// 情况2:没有盒子是空的dp[i][j] = dp[i-j][j]
			else dp[i][j] = dp[i][j-1]+dp[i-j][j];
		}
	}
	// 4. 求解
	return dp[m][n];
}

最大公共子串

int f(string s1, string s2) {
	int m = s1.length();
	int n = s2.length();
	// 1. 定义dp[i][j]为以s1[i]和s2[j]结尾的公共子串的长度
	int dp[m+1][n+1];
	int max = 0;
	// 2. 初始化
	for (int i=0; i<=m; i++) dp[i][0] = 0;
	for (int i=0; i<=n; i++) dp[0][i] = 0;
	// 3. 状态转移方程
	for (int i=1; i<=m; i++) {
		for (int j=1; j<=n; j++) {
			if (s1[i-1] == s2[j-1]) dp[i][j] = dp[i-1][j-1]+1;
      else dp[i][j] = 0;
      if (dp[i][j] > max) max = dp[i][j];
		}
	}
	// 4. 求解
	return max;
}

编辑距离

int f(string s1, string s2) {
	int len1 = s1.length();
	int len2 = s2.length();
	// 1. 定义dp[i][j]是s1前i个字符和s2前j个字符的编辑距离
	vector<vector<int>> dp(len1+1, vector<int>(len2+1, 0));
	// 2. 初始化
	for (int i=1; i<=len1; i++) dp[i][0] = i;
	for (int j=1; j<=len2; j++) dp[0][j] = j;
	for (int i=1; i<=len1; i++) {
		for (int j=1; j<=len2; j++) {
			// 3. 状态转移方程
			int t1 = dp[i-1][j]+1;
			int t2 = dp[i][j-1]+1;
			int t3 = dp[i-1][j-1]+1;
			if (s[i-1]==s[j-1]) t3--;
			dp[i][j] = min(t1, min(t2, t3));
		}
	}
	// 4. 求解
	return dp[len1][len2];
}

背包问题

int f(int N, int m) {
	// N是总钱数 m是可购买物品件数
	int v, p, prt;
	vector<vector<int>> data(m+1, vector<int>(6, 0));
	// 主件价格 主件重要度 从件1价格 从件1重要度 从件2价格 从件2重要度
	for (int i=1; i<=m; i++) {
		cin >> v >> p >> ptr;
		if (ptr == 0) {
			data[i][0] = v;
			data[i][1]= p;
		} else if (data[ptr][2] == 0) {
			data[ptr][2] = v;
			data[ptr][3] = p;
		} else {
			data[ptr][4] = v;
			data[ptr][5] = p;
		}
	}
	// 1. 定义dp[i][j]为购买i件商品用j元可以得到的最大的*价值重要度乘积*
	// 2. 初始化为0
	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 v1 = data[i][0];
				int v2 = data[i][2];
				int v3 = data[i][4];
				int p1 = data[i][1];
				int p2 = data[i][3];
				int p3 = data[i][5];
				// 3. 状态转移方程
				// case 1
				if (j>=v1) {
					int a = dp[i-1][j];
					int b = dp[i-1][j-v1]+v1*p1;
					dp[i][j] = max(a, b);
				} else {
					dp[i][j] = dp[i-1][j];
				}
				// case 2
				if (j>=(v1+v2)) {
					int a = dp[i][j];
					int b = dp[i-1][j-v1-v2]+v1*p1+v2*p2;
					dp[i][j] = max(a, b);
				} else {
					dp[i][j] = dp[i][j];
				}
				// case 3
				if (j>=(v1+v3)) {
					int a = dp[i][j];
					int b = dp[i-1][j-v1-v3]+v1*p1+v3*p3;
					dp[i][j] = max(a, b);
				} else {
					dp[i][j] = dp[i][j];
				}
				// case 4
				if (j>=(v1+v2+v3)) {
					int a = dp[i][j];
					int b = dp[i-1][j-v1-v2-v3]+v1*p1+v2*p2+v3*p3;
					dp[i][j] = max(a, b);
				} else {
					dp[i][j] = dp[i][j];
				}
		}
	}
	return dp[m][N];
}

3. HJ54表达式求值

// 返回在i位置的左括号对应的右括号的位置j
int close_quote(string s, int i, int r) {
	int layer = 0;
	int j = i;
	while (j <= r) {
		if (s[j] == '(') layer++;
		else if (s[j] == ')') {
			layer--;
			if (layer == 0) break;
		}
		j++;
	}
	return j;
}
// 计算字符串从位置l到位置r的计算结果的递归函数
int f(string s, int l, int r) {
	char op = '+';
	int num = 0;
	vector<int> v;
	for (int i=l; i<= r; i++) {
		if (isdigit(s[i])) num = num*10 + s[i]-'0';
		if (s[i] == '(') {
			int j = close_quote(s, i, r);
			num = f(s, i+1, j-1);
			i = j+1;
		}
		if (!isdigit(s[i]) || i == r) {
			switch(op) {
				case '+': v.push_back(num); break;
				case '-': v.push_back(-num); break;
				case '*': v.back() *= num; break;
				case '/': v.back() /= num; break;
			}
			op = s[i];
			num = 0;
		}
	}
	int res = 0;
	for (int i : v) res+=i;
	return res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值