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;
}
// 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;
}