OJ笔试强训
Day01
[NOIP2010]数字统计_牛客题霸_牛客网
点击消除_牛客题霸_牛客网
两个数组的交集_牛客题霸_牛客网
Day02
牛牛的快递_牛客题霸_牛客网
最小花费爬楼梯_牛客题霸_牛客网
数组中两个字符串的最小距离__牛客网
Day03
简写单词_牛客题霸_牛客网
dd爱框框_牛客题霸_牛客网
除2!(0/40分)
除2!_牛客题霸_牛客网
没开long long直接0分。。。。。。。。。。。。。。。。
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
#define int long long
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n = 0, k = 0;
cin >> n >> k;
// vector<int> v(n);
int x = 0; // 可以不开数组,直接一个变量接收
int sum = 0;
priority_queue<int> q; // 存偶数的堆
for (int i = 0; i < n; ++i)
{
/*cin >> v[i];
sum += v[i];
if (v[i] % 2 == 0)
q.push(v[i]);*/
cin >> x;
sum += x;
if(x % 2 == 0)
q.push(x);
}
while (k-- && !q.empty())
{
int x = q.top() / 2;
q.pop();
sum -= x;
if (x % 2 == 0)
q.push(x);
}
cout << sum;
return 0;
}
Day04
Fibonacci数列_牛客题霸_牛客网
单词搜索(26.33/30)
单词搜索_牛客题霸_牛客网
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param board string字符串vector
* @param word string字符串
* @return bool布尔型
*/
int dx[4] = { 0, 0, -1, 1 };
int dy[4] = { 1, -1, 0, 0 };
bool vis[101][101];
int m = 0, n = 0;
bool exist(vector<string>& board, string word) {
m = board.size(), n = board[0].size();
if (word.size() > m * n)
return false;;
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
{
if (board[i][j] == word[0])
{
if (dfs(board, i, j, 0, word) == true) // 从0开始写成从1开始的版本,然后几个用例没过
return true;
}
}
}
return false;
}
bool dfs(vector<string>& board, int sr, int sc, int pos, string& word)
{
if (pos == word.size() - 1)
return true;
vis[sr][sc] = true;
for (int i = 0; i < 4; ++i)
{
int x = sr + dx[i], y = sc + dy[i];
if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && word[pos + 1] == board[x][y]) // pos少+1了
{
// if(pos == word.size())
// return true;
// return dfs(board, x, y, pos + 1, word);
// 这两行写成上一行了
if(dfs(board, x, y, pos + 1, word))
return true;
}
}
vis[sr][sc] = false; // 恢复现场!!!!!!!!!!!这行没写
return false;
}
};
杨辉三角_牛客题霸_牛客网
Day05
游游的you_贪心+模拟
腐烂的苹果_多源BFS
孩子们的游戏_约瑟夫环
Day06
大数加法_牛客题霸_牛客网
链表相加(二)_牛客题霸_牛客网
大数乘法_牛客题霸_牛客网
Day07
字符串中找出连续最长的数字串_双指针
岛屿数量_BFS/DFS
拼三角_枚举/DFS
Day08
9.29第一篇
求最小公倍数_牛客题霸_牛客网
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
int main()
{
int a = 0, b = 0;
cin >> a >> b;
if (a > b)
swap(a, b);
int c = __gcd(a, b); // 9 6 -> 3 -> 18
cout << a * b / c << endl; // !!!!!两者乘积除以最大公约数
// if(c == 1)
// {
// cout << a * b << endl;
// return 0;
// }
// else if(c == a)
// {
// cout << b << endl;
// return 0;
// }
// else
// {
// if(c * b % a == 0)
// {
// cout << b * c << endl;
// return 0;
// }
// else if(c * a % b == 0)
// {
// cout << c * a << endl;
// return 0;
// }
// }
// for (int i = b; i <= a * b; i += c)
// {
// if (i % a == 0 && i % b == 0)
// {
// cout << i << endl;
// break;
// }
// }
return 0;
}
数组中的最长连续子序列(0/30)没去重直接0分
数组中的最长连续子序列_牛客题霸_牛客网
#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* max increasing subsequence
* @param arr int整型vector the array
* @return int整型
*/
int MLS(vector<int>& arr) {
set<int> s(arr.begin(), arr.end());
vector<int> nums(s.begin(), s.end());
sort(nums.begin(), nums.end()); // 排序+遍历一遍
int sz = nums.size();
int ret = 1;
for (int i = 1; i < sz; ++i)
{
int len = 1;
while (nums[i] - nums[i - 1] == 1)
{
++len;
++i;
}
cout << ret << " " << len << endl;
ret = max(ret, len);
}
return ret;
}
};
字母收集_牛客题霸_牛客网
Day09
添加逗号_牛客题霸_牛客网
跳台阶_牛客题霸_牛客网
扑克牌顺子_牛客题霸_牛客网
原代码:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param numbers int整型vector
* @return bool布尔型
*/
bool IsContinuous(vector<int>& numbers) {
vector<int> arr(13, 0);
int cnt = 0; // 非0的个数
for (auto& e : numbers)
{
arr[e]++;
if (e != 0)
++cnt;
}
if (arr[0] == 4) // 保证下面有两个不同的边界
return true;
int left = 0, right = 0;
for (int i = 1; i <= 13; ++i)
{
if (arr[i] > 1) // 保证去重
{
cout << "有重复";
return false;
}
if (arr[i] != 0)
{
left = i;
break;
}
}
for (int i = 13; i > left; --i)
{
if (arr[i] != 0)
{
right = i;
break;
}
}
// cout << left << " " << right << endl;
// 0 0 2 4 6 left = 2, right = 6;
int sum = right - left - 1; // 中间应该有的个数
sum -= cnt - 2; // 减去中间已经有的个数
// cout << "sum " << sum << " arr[0]" << arr[0] << endl;
if (sum <= arr[0])
return true;
else
return false;
}
};
在原代码的基础上改的答案:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param numbers int整型vector
* @return bool布尔型
*/
bool IsContinuous(vector<int>& numbers) {
vector<int> arr(13, 0);
int cnt = 0; // 非0的个数
for (auto& e : numbers)
{
arr[e]++;
if (e != 0)
++cnt;
}
if (arr[0] == 4) // 保证下面有两个不同的边界
{
cout << "line 21" << endl;
return true;
}
int left = 0, right = 0;
for (int i = 1; i <= 13; ++i)
{
if (arr[i] > 1) // 保证去重
{
// cout << "有重复";
return false;
}
}
for (int i = 1; i <= 13; ++i) // 找左边界
{
if (arr[i] != 0)
{
left = i;
break;
}
}
for (int i = 13; i > left; --i) // 找右边界
{
if (arr[i] != 0)
{
right = i;
break;
}
}
// cout << left << " " << right << endl;
// 0 0 2 4 6 left = 2, right = 6;
int sum = right - left - 1; // 中间应该有的个数
sum -= cnt - 2; // 减去中间已经有的个数
// cout << "sum " << sum << " arr[0]" << arr[0] << endl;
if (sum <= arr[0])
return true;
else
return false;
}
};
找规律的代码
#include <climits>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param numbers int整型vector
* @return bool布尔型
*/
bool IsContinuous(vector<int>& numbers) {
// 找规律->不会出现重复元素 && max - min >= 4
vector<int> arr(13, 0);
int minLeft = INT_MAX, maxRight = INT_MIN; // 找最大最小值
for (auto& e : numbers)
{
if(e == 0)
continue;
minLeft = min(minLeft, e);
maxRight = max(maxRight, e);
arr[e]++;
if(arr[e] > 1)
return false;
}
return maxRight - minLeft <= 4;
}
};
Day10
10.2第一篇
过河卒(36.36/40)没开long long
[NOIP2002 普及组] 过河卒_牛客题霸_牛客网
原代码改longlong
#include <iostream>
#include <ostream>
#include <vector>
using namespace std;
#define int long long // 66666666666666666666666666666666666666666666
signed main()
{
// 把马吃了是不是后面的点就能走了?emmm
int n = 0, m = 0, x = 0, y = 0;
cin >> n >> m >> x >> y;
// if (n == 1 || m == 1) // 边界处理
// {
// cout << 1 << endl;
// return 0;
// }
// if (abs(m - x) + abs(n - y) == 3 && m != x && n != y)
// {
// cout << 0 << endl;
// return 0;
// }
// vector<vector<int>> borad(n, vector<int>(m));
vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
for (int i = 0; i <= n; ++i)
{
if (abs(i - x) + abs(0 - y) == 3 && i != x && 0 != y)
break;
if (x == i && y == 0) // 马也不能走!!!真服了
break;
dp[i][0] = 1;
}
for (int j = 0; j <= m; ++j)
{
if (abs(0 - x) + abs(j - y) == 3 && 0 != x && j != y)
break;
if (x == 0 && y == j) // 马也不能走!!!真服了
break;
dp[0][j] = 1;
}
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
if (abs(i - x) + abs(j - y) == 3 && i != x && j != y)
continue;
if (x == i && y == j) // 马也不能走!!!真服了
continue;
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
// for(int i = 0; i <= n; ++i) // DeBug:打印dp矩阵
// {
// for(int j = 0; j <= m; ++j)
// {
// cout << dp[i][j] << " ";
// }
// cout << endl;
// }
cout << dp[n][m] << endl;
return 0;
}
优化代码
#include <iostream>
#include <ostream>
#include <vector>
using namespace std;
#define int long long // 66666666666666666666666666666666666666666666
signed main()
{
// 把马吃了是不是后面的点就能走了?emmm
int n = 0, m = 0, x = 0, y = 0;
cin >> n >> m >> x >> y;
// if (n == 1 || m == 1) // 边界处理
// {
// cout << 1 << endl;
// return 0;
// }
// if (abs(m - x) + abs(n - y) == 3 && m != x && n != y)
// {
// cout << 0 << endl;
// return 0;
// }
// vector<vector<int>> borad(n, vector<int>(m));
vector<vector<int>> dp(n + 2, vector<int>(m + 2, 0));
// for (int i = 0; i <= n; ++i)
// {
// if (abs(i - x) + abs(0 - y) == 3 && i != x && 0 != y)
// break;
// if (x == i && y == 0) // 马也不能走!!!真服了
// break;
// dp[i][0] = 1;
// }
// for (int j = 0; j <= m; ++j)
// {
// if (abs(0 - x) + abs(j - y) == 3 && 0 != x && j != y)
// break;
// if (x == 0 && y == j) // 马也不能走!!!真服了
// break;
// dp[0][j] = 1;
// }
dp[0][1] = 1;
x += 1, y += 1;
for (int i = 1; i <= n + 1; ++i)
{
for (int j = 1; j <= m + 1; ++j)
{
if (abs(i - x) + abs(j - y) == 3 && i != x && j != y)
continue;
if (x == i && y == j) // 马也不能走!!!真服了
continue;
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
// for(int i = 0; i <= n; ++i) // DeBug:打印dp矩阵
// {
// for(int j = 0; j <= m; ++j)
// {
// cout << dp[i][j] << " ";
// }
// cout << endl;
// }
cout << dp[n + 1][m + 1] << endl;
return 0;
}
Day11
游游的水果大礼包(21.67/30)贪心是错解
登录—专业IT笔试面试备考平台_牛客网
原代码(贪心emmmmm)
(过了百分之72,开long long后过了百分之78)
#include <iostream>
using namespace std;
int main()
{
int n = 0, m = 0, a = 0, b = 0;
cin >> n >> m >> a >> b;
int res = 0;
if (a > b) // 先组成a
{
if (n >= 2 && m >= 1)
{
res += min(n / 2, m) * a;
if (res / a == n / 2)
{
m -= n / 2;
n %= 2;
}
else
{
n -= m;
m = 0;
}
}
if (n >= 1 && m >= 2)
{
res += min(n, m / 2) * b;
}
}
else // 先组成b
{
if (n >= 1 && m >= 2)
{
res += min(n, m / 2) * b;
// cout << res << " " << n << " " << m << " " << endl;
if (res / b == m / 2)
{
n -= m / 2;
m %= 2;
}
else
{
m -= n;
n = 0;
}
}
// cout << n << " " << m << endl;
if (n >= 2 && m >= 1)
{
res += min(n / 2, m) * a;
}
}
cout << res << endl;
return 0;
}
枚举_正解
#include <iostream>
using namespace std;
#define int long long
signed main()
{
int n = 0, m = 0, a = 0, b = 0;
cin >> n >> m >> a >> b;
int res = 0;
// 2x + 3y = ? 条件太少就枚举
for(int x = 0; x <= min(n / 2, m); ++x) // 枚举x
{
int y = min(n - 2 * x, (m - x) / 2);
res = max(res, a * x + b * y);
}
cout << res << endl;
return 0;
}
Day12(没考!!!)
删除公共字符(简单模拟,两分钟AC)
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;
int main()
{
string str1, str2;
getline(cin, str1);
getline(cin, str2);
unordered_map<char, int> hash; // str2的字母和个数
for(auto& e : str2)
{
hash[e]++;
}
string res;
for(auto& e : str1)
{
if(!hash.count(e))
res += e;
}
cout << res << endl;
return 0;
}
两个链表的第一个公共结点
解法一(双指针_长的先走)
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode* cur1 = pHead1;
int cnt1 = 0, cnt2 = 0;
while(cur1 != nullptr)
{
cnt1++;
cur1 = cur1->next;
}
ListNode* cur2 = pHead2;
while(cur2 != nullptr)
{
cnt2++;
cur2 = cur2->next;
}
// cout << pHead1->val << " " << pHead2->val << endl;
if(cnt1 < cnt2)
swap(pHead1, pHead2);
cur1 = pHead1, cur2 = pHead2;
// cout << pHead1->val << " " << pHead2->val << endl;
int diff = abs(cnt1 - cnt2);
while(diff--)
{
cur1 = cur1->next;
}
while(cur1 != nullptr && cur2 != nullptr)
{
// cout <<cur1->val << " " << cur2->val << endl;
if(cur1->val == cur2->val)
return cur1;
cur1 = cur1->next;
cur2 = cur2->next;
}
return nullptr;
}
};
解法二(等量关系)
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
auto cur1 = pHead1, cur2 = pHead2; // 解法二-等量关系
while(cur1 != cur2)
{
cur1 = cur1 != nullptr ? cur1->next : pHead2; // 为空就到另个链表重新走
cur2 = cur2 != nullptr ? cur2->next : pHead1;
}
return cur1;
}
};
mari和shiny(没想到用什么解法。。dp)
直接dp
#include <iostream>
#include <vector>
using namespace std;
#define int long long
signed main()
{
int n = 0;
string str;
cin >> n >> str;
vector<int> s(n), h(n), y(n);
s[0] = str[0] == 's' ? 1 : 0;
for(int i = 1; i < n; ++i)
{
s[i] = s[i - 1];
if(str[i] == 's')
s[i] += 1;
h[i] = h[i - 1];
if(str[i] == 'h')
h[i] += s[i - 1];
y[i] = y[i - 1];
if(str[i] == 'y')
y[i] += h[i - 1];
}
cout << y[n - 1] << endl;
return 0;
}
用变量进行空间优化
#include <iostream>
#include <vector>
using namespace std;
#define int long long
signed main()
{
int n = 0;
string str;
cin >> n >> str;
// vector<int> s(n), h(n), y(n); // 用变量进行空间优化
int s = 0, h = 0, y = 0;
s = str[0] == 's' ? 1 : 0;
for(int i = 1; i < n; ++i)
{
if(str[i] == 's')
s += 1;
if(str[i] == 'h')
h += s;
if(str[i] == 'y')
y += h;
}
cout << y << endl;
return 0;
}
Day13
牛牛冲钻五(模拟AC)
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int T = 0;
cin >> T;
while (T--)
{
int n = 0, k = 0;
string str;
cin >> n >> k >> str;
int res = 0;
for (int i = 0; i < n; ++i)
{
if (i >= 2 && str[i - 2] == 'W' && str[i - 1] == 'W' && str[i] == 'W') {
res += k;
}
else if (str[i] == 'W') {
++res;
}
else {
--res;
}
}
cout << res << endl;
}
return 0;
}
最长无重复子数组(21.82/30)
最长无重复子数组_牛客题霸_牛客网 (nowcoder.com)
暴力(N^2但AC了)
#include <ostream>
#include <unordered_set>
#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param arr int整型vector the array
* @return int整型
*/
int maxLength(vector<int>& arr) {
int res = 1, sz = arr.size();
for (int i = 0; i < sz; ++i) // 暴力
{
int len = 1;
vector<bool> hash(100001, false);
hash[arr[i]] = true;
for (int j = i + 1; j < sz && hash[arr[j]] == false; ++j)
{
++len;
hash[arr[j]] = true;
}
res = max(res, len);
}
// for (int i = 0; i < sz; ) // 笔试时写的,8/11
// {
// int len = 1;
// vector<bool> hash(100001, false);
// hash[arr[i++]] = true;
// while (i < sz && hash[arr[i]] == false)
// {
// ++len;
// hash[arr[i]] = true;
// ++i;
// }
// res = max(res, len);
// }
return res;
}
};
滑动窗口
#include <ostream>
#include <unordered_set>
#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param arr int整型vector the array
* @return int整型
*/
int maxLength(vector<int>& arr) {
int res = 1, sz = arr.size();
for (int i = 0; i < sz; ++i) // 暴力
{
int len = 1;
vector<bool> hash(100001, false);
hash[arr[i]] = true;
for (int j = i + 1; j < sz && hash[arr[j]] == false; ++j)
{
++len;
hash[arr[j]] = true;
}
res = max(res, len);
}
// for (int i = 0; i < sz; ) // 笔试时写的,8/11
// {
// int len = 1;
// vector<bool> hash(100001, false);
// hash[arr[i++]] = true;
// while (i < sz && hash[arr[i]] == false)
// {
// ++len;
// hash[arr[i]] = true;
// ++i;
// }
// res = max(res, len);
// }
return res;
}
};
#include <ostream>
#include <unordered_set>
#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param arr int整型vector the array
* @return int整型
*/
int hash[100001] = { 0 };
int maxLength(vector<int>& arr) {
int res = 1, sz = arr.size();
for (int left = 0, right = 0; right < sz; ++right) // 滑动窗口
{
hash[arr[right]]++; // 进窗口
while (left < sz && hash[arr[right]] > 1) // 判断
{
hash[arr[left++]]--; // 出窗口
}
res = max(res, right - left + 1);
}
// for (int i = 0; i < sz; ++i) // 暴力
// {
// int len = 1;
// vector<bool> hash(100001, false);
// hash[arr[i]] = true;
// for (int j = i + 1; j < sz && hash[arr[j]] == false; ++j)
// {
// ++len;
// hash[arr[j]] = true;
// }
// res = max(res, len);
// }
// for (int i = 0; i < sz; ) // 笔试时写的,8/11
// {
// int len = 1;
// vector<bool> hash(100001, false);
// hash[arr[i++]] = true;
// while (i < sz && hash[arr[i]] == false)
// {
// ++len;
// hash[arr[i]] = true;
// ++i;
// }
// res = max(res, len);
// }
return res;
}
};
重排字符串(26.67/40)
原代码
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n = 0;
string str;
cin >> n >> str;
vector<int> hash(26, 0);
int sz = str.size();
for (int i = 0; i < sz; ++i)
{
hash[str[i] - 'a']++;
}
int maxCnt = 0, maxIndex = 0;
int secCnt = 0, secIndex = 0;
for (int i = 0; i < 26; ++i) // 要放第一大然后放第二大?跟着下标排序
{
if (hash[i] > maxCnt)
{
maxCnt = hash[i];
maxIndex = i;
}
}
for (int i = 0; i < 26; ++i) // 要放第一大然后放第二大?跟着下标排序
{
if (i != maxIndex && hash[i] > secCnt)
{
secCnt = hash[i];
secIndex = i;
}
}
if (maxCnt > sz / 2)
cout << "no";
else
{
cout << "yes" << endl;
vector<char> res(n, '1');
int i = 0;
while (maxCnt--)
{
res[i] = (maxIndex + 'a');
i += 2;
}
if (i > n - 1)
i = 1;
// while(secCnt--)
// {
// res[i] = (secIndex + 'a');
// i += 2;
// }
// if(i > n - 1)
// i = 1;
int j = 0;
while (res[n - 1] == '1' || res[n - 2] == '1')
{
if (j != maxIndex && hash[j] != 0) // 找到一个后往后找
{
res[i] = (j + 'a'); // 不等于0就放入一个然后往hash后面找
// cout << i << " res[i] : " << res[i] << " hash[j] " << hash[j] << endl;
i += 2;
if (i > n - 1)
i = 1;
hash[j]--;
}
if (j == 25)
j = 0;
else
++j;
}
for (auto& e : res)
{
cout << e;
}
}
return 0;
}
正解
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int n = 0;
string str;
cin >> n >> str;
vector<int> hash(26, 0);
int sz = str.size();
for (int i = 0; i < sz; ++i)
{
hash[str[i] - 'a']++;
}
int maxCnt = 0, maxIndex = 0;
for (int i = 0; i < 26; ++i) // 先放第一大
{
if (hash[i] > maxCnt)
{
maxCnt = hash[i];
maxIndex = i;
}
}
if (maxCnt > (sz + 1) / 2)
cout << "no";
else
{
cout << "yes" << endl;
vector<char> res(n);
int i = 0;
while (maxCnt--)
{
res[i] = (maxIndex + 'a');
i += 2;
}
// cout << maxIndex << endl;
for (int j = 0; j < 26; ++j)
{
if (j != maxIndex && hash[j] != 0) // 找到一个后往后找
{
while(hash[j]--)
{
if(i >= n)
i = 1;
res[i] = j + 'a';
i += 2;
}
}
}
for (auto& e : res)
{
cout << e;
}
cout << endl;
}
return 0;
}
Day14
乒乓球筐__牛客网 (nowcoder.com)
组队竞赛_牛客笔试题_牛客网 (nowcoder.com)
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
using namespace std;
// 偷房子那题?dp
#define int long long
signed main()
{
int n = 0;
cin >> n;
unordered_map<int, int> hash;
vector<int> v(n);
for(int i = 0; i < n; ++i)
{
cin >> v[i];
hash[v[i]] += v[i];
}
vector<int> arr;
for(auto [a, b] : hash)
{
arr.push_back(a);
// cout << a << " " << b << endl;
}
sort(arr.begin(), arr.end());
// dp[0][i]表示从第0个元素开始选到第i个元素结束
// dp[1][i]表示从第1个元素开始选到第i个元素结束
int res1 = 0, res2 = 0;
for(int i = 0; i < n; i += 2)
{
res1 += hash[arr[i]];
}
for(int i = 1; i < n; i += 2)
{
res2 += hash[arr[i]];
}
cout << max(res1, res2) << endl;
// dp[i][j]表示选择第n个元素开始,到第j个元素结束
// 选j -> dp[i][j] = dp[i][j - 2] + v[j]
// 不选j-> dp[i][j] = max(dp[i][j - 1], dp[i][j - 2]);
return 0;
}
/* Day14_2,组队竞赛
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
/*
2
5 2 8 5 1 5 -> 1 5 8 ,2 5 5用例说明错了吧
1 2 5 5 5 8 (最小,第二大,第一大)
5 2 8 5 1 5 9 9 9
1 9 9 ,2 8 9 , 5 5 5
#define int long long
signed main()
{
int n = 0;
cin >> n;
n *= 3;
priority_queue<int> q;
int x = 0;
for(int i = 0; i < n; ++i)
{
cin >> x;
q.push(x);
}
int res = 0;
for(int i = n / 3; i < n - n / 3; ++i)
{
q.pop();
// cout << q.top() << " ";
res += q.top();
q.pop();
}
cout << res << endl;
return 0;
}
*/
/* // Day14_1,乒乓球框
#include <iostream>
#include <vector>
using namespace std;
int main()
{
string str1, str2;
cin >> str1 >> str2;
vector<int> hash1(26, 0), hash2(26, 0);
for(auto& e : str1)
{
hash1[e - 'A']++;
}
for(auto& e : str2)
{
hash2[e - 'A']++;
}
for(int i = 0; i < 26; ++i)
{
if(hash1[i] < hash2[i])
{
cout << "No";
return 0;
}
}
cout << "Yes";
return 0;
}
*/
删除相邻数字的最大分数
删除相邻数字的最大分数_牛客题霸_牛客网
#include <iostream>
#include <unordered_map>
#include <vector>
#include <algorithm>
using namespace std;
// 偷房子那题?dp
const int N = 1e4 + 7;
int main()
{
int n = 0;
cin >> n;
vector<int> hash(N);
int x = 0;
for(int i = 0; i < n; ++i)
{
cin >> x;
hash[x] += x;
}
vector<int> f(N), g(N); // f是选,g是不选
for(int i = 1; i < N; ++i)
{
f[i] = g[i - 1] + hash[i];
g[i] = max(f[i - 1], g[i - 1]);
}
cout << max(f[N - 1], g[N - 1]);
return 0;
/*
unordered_map<int, int> hash;
vector<int> v(n);
for(int i = 0; i < n; ++i)
{
cin >> v[i];
hash[v[i]] += v[i];
}
vector<int> arr;
for(auto [a, b] : hash)
{
arr.push_back(a);
// cout << a << " " << b << endl;
}
sort(arr.begin(), arr.end());
// dp[0][i]表示从第0个元素开始选到第i个元素结束
// dp[1][i]表示从第1个元素开始选到第i个元素结束
int res1 = 0, res2 = 0;
for(int i = 0; i < n; i += 2)
{
res1 += hash[arr[i]];
}
for(int i = 1; i < n; i += 2)
{
res2 += hash[arr[i]];
}
cout << max(res1, res2) << endl;
// dp[i][j]表示选择第n个元素开始,到第j个元素结束
// 选j -> dp[i][j] = dp[i][j - 2] + v[j]
// 不选j-> dp[i][j] = max(dp[i][j - 1], dp[i][j - 2]);
return 0;*/
}
Day15(两题不会,代码还忘记保存了)
平方数(用的暴力)下面有数学的解法:
登录—专业IT笔试面试备考平台_牛客网
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
#define int long long
signed main()
{
int x = 0;
cin >> x;
// vector<int> v; // 用两个变量优化
int i = 1;
int prev = 0, next = 0;
do
{
// v.push_back(i * i);
prev = next;
next = i * i;
++i;
} while (next < x);
if (next == x)
cout << x << endl;
else if (next - x < x - prev)
cout << next << endl;
else
cout << prev << endl;
// if(v.back() == x)
// cout << x << endl;
// else if(v.back() - x < x - v[v.size() - 2])
// cout << v.back() << endl;
// else
// cout << v[v.size() - 2] << endl;
return 0;
}
数学解法:
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define int long long
signed main()
{
int x = 0;
cin >> x;
int n = sqrt(x);
int prev = n * n, next = (n + 1) * (n + 1);
if(x - prev < next - x)
{
cout << prev << endl;
}
else
{
cout << next << endl;
}
return 0;
}
分组 (nowcoder.com)
拓扑排序(被卡了最后不能输出空格)
#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>
using namespace std;
const int N = 2 * 1e5 + 1;
int main()
{
int n = 0, m = 0;
cin >> n >> m;
int x = 0, y = 0;
unordered_map<int, vector<int>> Edge;
vector<int> in(N);
while (cin >> x >> y) // x 指向 y
{
Edge[x].push_back(y);
in[y]++;
}
// for(auto& [a, b] : Edge)
// {
// cout << a << " -> ";
// for(auto& e : b)
// {
// cout << e << " ";
// }
// cout << endl;
// }
// for(auto& e : in)
// {
// if(e != 0)
// cout << e << " ";
// }
// cout << endl;
priority_queue<int> q;
for (int i = 1; i <= n; ++i)
{
if (in[i] == 0)
{
q.push(i);
// cout << "begin" << i;
}
}
vector<int> res;
while (q.size())
{
int tmp = q.top();
q.pop();
res.push_back(tmp);
for (auto& e : Edge[tmp]) // tmp指向的边的入度减一
{
in[e]--;
if (in[e] == 0) // 减为0了就进队列
q.push(e);
}
// // Edge.erase(tmp); // 加这步?
// for(auto& [a, b] : Edge)
// {
// cout << a << " -> ";
// for(auto& e : b)
// {
// cout << e << " ";
// }
// cout << endl;
// }
// for(int i = 1; i <= n; ++i)
// {
// cout << in[i] << " ";
// }
// cout << endl;
}
if(res.size() != n)
{
cout << -1;
}
else
{
for (int i = 0; i < n - 1; ++i)
{
cout << res[i] << " ";
}
cout << res[n - 1]; // 666666666666666
}
return 0;
}
Day16(全对)
字符串替换_牛客题霸_牛客网 (nowcoder.com)
神奇数_牛客笔试题_牛客网 (nowcoder.com)
DNA序列_牛客题霸_牛客网 (nowcoder.com)
#include <climits>
#include <iostream>
using namespace std;
int main() // Day16_3 双指针?
{
string str;
int n = 0;
cin >> str >> n;
int sz = str.size();
int cnt = 0; // 统计C和G数量
int begin = 0, cur = 0, maxCnt = INT_MIN;
while(cur < sz - n)
{
cnt = 0;
for(int i = cur; i < cur + n; ++i)
{
if(str[i] == 'C' || str[i] == 'G')
++cnt;
}
if(cnt > maxCnt)
{
begin = cur;
maxCnt = cnt;
}
++cur;
}
string res(str.begin() + begin, str.begin() + begin + n);
cout << res << endl;
return 0;
}
/*
#include <cmath> // Day16_2
#include <iostream>
#include <string>
using namespace std;
bool isPrime(int x) // 判断是否是质数
{
for(int i = 2; i <= sqrt(x); ++i)
{
if(x % i == 0)
return false;
}
return true;
}
bool isTrue(int x) // 判断是否是神奇数
{
string str = to_string(x);
int sz = str.size();
for(int i = 0; i < sz; ++i) // 枚举十位数
{
if(str[i] == '0')
continue;
for(int j = 0; j < sz; ++j) // 枚举个位数
{
if(j != i && isPrime((str[i] - '0') * 10 + (str[j] - '0')))
return true;
}
}
return false;
}
int main()
{
int a = 0, b = 0;
cin >> a >> b;
int cnt = 0;
for(int i = a; i <= b; ++i)
{
if(isTrue(i))
++cnt;
}
cout << cnt << endl;
return 0;
}
*/
/*
#include <cctype> // Day16_1
class Solution {
public:
string formatString(string str, vector<char>& arg) {
string ret;
int sz1 = str.size(), sz2 = arg.size();
int j = 0;
for(int i = 0; i < sz1; ++i)
{
if(isupper(str[i]) || islower(str[i]))
{
if(i != 0 && str[i - 1] == '%')
continue;
ret += str[i];
}
if(str[i] == '%')
ret += arg[j++];
}
while(j < sz2)
{
ret += arg[j++];
}
return ret;
}
};
*/
Day17_第三题不会
压缩字符串
小乐乐改数字_牛客题霸_牛客网
#include <algorithm>
#include <cstdlib>
#include <iostream>
using namespace std;
int main() // Day17_1_简单模拟
{
int n = 0;
cin >> n;
string tmp;
while (n)
{
int val = n % 10;
if (val % 2 == 0)
tmp += "0";
else
tmp += "1";
n /= 10;
}
reverse(tmp.begin(), tmp.end());
int res = atoi(tmp.c_str());
cout << res;
return 0;
}
十字爆破
十字爆破
#include <iostream>
#include <vector>
using namespace std;
#define int long long
signed main() // Day17_2_时间O(N^2),前缀和?-> 每一行和每一列的和,
{
int n = 0, m = 0;
cin >> n >> m;
vector<vector<int>> vv(n, vector<int>(m));
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
scanf("%lld", &vv[i][j]);
}
}
vector<int> sum1(n); // 每一行的和
for (int i = 0; i < n; ++i) // 每一行
{
for (int j = 0; j < m; ++j) // 每一列
{
sum1[i] += vv[i][j];
}
}
// for(int i = 0; i < n; ++i)
// {
// cout << sum1[i] << " ";
// }
// cout << endl << endl;
vector<int> sum2(m); // 每一列的和
for (int j = 0; j < m; ++j) // 每一列
{
for (int i = 0; i < n; ++i) // 每一行
{
sum2[j] += vv[i][j]; // j i
}
}
// for(int i = 0; i < n; ++i)
// {
// cout << sum2[i] << " ";
// }
// cout << endl << endl;
vector<vector<int>> res(n, vector<int>(m));
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
// res[i][j] = sum1[i] + sum2[j];
// cout << sum1[i] + sum2[j] - vv[i][j] << " ";
printf("%lld ", sum1[i] + sum2[j] - vv[i][j]);
}
printf("\n");
}
return 0;
}
比那名居的桃子(15/40)滑动窗口/前缀和
比那名居的桃子 (nowcoder.com)
原代码:
#include <climits>
#include <ios>
#include <iostream>
#include <vector>
using namespace std;
#define int long long
signed main() // Day17_3_dp? 滑动窗口选快乐值->选不了多段?->两次。
// n和k还有限制太难了,放弃? n好像不是限制。。。。
{
int n = 0, k = 0;
cin >> n >> k;
vector<int> a(n), b(n);
for (int i = 0; i < n; ++i)
cin >> a[i];
for (int i = 0; i < n; ++i)
cin >> b[i];
int maxHappy = INT_MIN;
int tmp = 0;
for (int left = 0, right = 0; right < n; ++right)
{
if (right - left <= k)
tmp += a[right]; // 进窗口
while (tmp > maxHappy) // 判断
{
if (right - left >= k)
tmp -= a[left++]; // 出窗口
if (tmp > maxHappy)
maxHappy = tmp; // 更新结果
}
// cout << "tmp2 " << tmp << " left " << left << " right " << right << endl;
}
// cout << maxHappy << endl << endl;
vector<int> index; // 存储最大快乐数区间的左下标
int maxHappyTmp = INT_MIN + 2;
tmp = 0;
for (int left = 0, right = 0; right < n; ++right)
{
if (right - left <= k)
tmp += a[right]; // 进窗口
while (tmp > maxHappyTmp) // 判断
{
if (right - left >= k)
tmp -= a[left++]; // 出窗口
if (tmp >= maxHappyTmp)
{
maxHappyTmp = tmp; // 更新结果
if (maxHappyTmp == maxHappy)
index.push_back(left);
}
}
}
int b_min = INT_MAX, res = 0;
for (auto& e : index)
{
// cout << e << " ";
tmp = 0;
for (int i = e; i < k + e; ++i)
{
tmp += b[i];
// cout << i << " ";
}
if (tmp < b_min)
{
res = e;
b_min = tmp;
}
}
cout << res + 1 << endl;
return 0;
}
AC代码:
#include <climits>
#include <ios>
#include <iostream>
#include <vector>
using namespace std;
#define int long long
signed main() // Day17_3_dp? 滑动窗口选快乐值->选不了多段?->两次。
// n和k还有限制太难了,放弃? n好像不是限制。。。。
{
int n = 0, k = 0; // 看了题解后,k是滑动窗口的大小。。。。。
cin >> n >> k;
vector<int> a(n), b(n);
for (int i = 0; i < n; ++i)
cin >> a[i];
for (int i = 0; i < n; ++i)
cin >> b[i];
int aSum = 0, bSum = 0, res = 0;
int aMax = INT_MIN, bMin = INT_MAX;
for (int left = 0, right = 0; right < n; ++right)
{
aSum += a[right]; // 进窗口
bSum += b[right]; // 进窗口
while(right - left + 1 > k) // 判断
{
aSum -= a[left];
bSum -= b[left];
++left; // 出窗口
}
if(aSum > aMax || (aSum == aMax && bSum < bMin)) // 更新结果
{
res = left;
aMax = aSum;
bMin = bSum;
}
}
cout << res + 1 << endl;
return 0;
}
Day18(代码没保存)
压缩字符串(一)(19.09/30)_9以上的数字不能直接+'0'转成字符,要to_string
#include <string>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param param string字符串
* @return string字符串
*/
string compressString(string param) {
int left = 0, right = 1, sz = param.size();
string ret;
while (right < sz)
{
int cnt = 1;
while (param[left] == param[right])
{
++cnt;
++right;
}
ret += param[left];
if (cnt != 1)
ret += to_string(cnt);
// ret += cnt + '0'; // !!!!!!!!!!!!
left = right;
++right;
}
if (left == sz - 1)
ret += param[left];
// cout << left << " " << right << " " << sz << endl;
return ret;
}
};
chika和蜜柑 (nowcoder.com)
#include <iostream>
#include <ostream>
#include <queue>
#include <utility>
#include <vector>
using namespace std;
struct cmp
{
bool operator()(pair<int, int> p1, pair<int, int> p2) // 堆的比较和逻辑相反
{
if (p1.first > p2.first)
return false;
else if (p1.first == p2.first)
return p1.second > p2.second;
else
return true;
}
};
#define int long long
signed main()
{
int n = 0, k = 0;
cin >> n >> k;
// vector<int> a(n), b(n);
priority_queue<pair<int, int>, vector<pair<int, int>>, cmp> qb;
vector<int> a(n);
for (int i = 0; i < n; ++i)
{
cin >> a[i];
}
int x = 0;
for (int i = 0; i < n; ++i)
{
cin >> x;
qb.push({ x, a[i] });
}
// while(qb.size())
// {
// cout << qb.top().first << " " << qb.top().second << endl;
// qb.pop();
// }
// cout << "-------------" << endl;
int sum1 = 0, sum2 = 0;
while (qb.size() && k--)
{
sum2 += qb.top().first;
sum1 += qb.top().second;
qb.pop();
}
cout << sum1 << " " << sum2 << endl;
return 0;
}
01背包_牛客题霸_牛客网
#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 计算01背包问题的结果
* @param V int整型 背包的体积
* @param n int整型 物品的个数
* @param vw int整型vector<vector<>> 第一维度为n,第二维度为2的二维数组,vw[i][0],vw[i][1]分别描述i+1个物品的vi,wi
* @return int整型
*/
int knapsack(int V, int n, vector<vector<int> >& vw) {
// vector<vector<int>> dp(n + 7, vector<int>(V + 7)); // 0到i最大重量,体积不超过j
// // 不选,dp[i][j] = dp[i - 1][j]
// 选,dp[i][j] = dp[i - 1][j - vw[i - 1][2]] + vw[i - 1][1]
//for (int i = 1; i <= n; ++i)
//{
// for (int j = 0; j <= V; ++j)
// {
// dp[i][j] = dp[i - 1][j];
// if (j - vw[i - 1][0] >= 0)
// {
// // cout << j << " " << vw[i - 1][0] << endl;
// dp[i][j] = max(dp[i][j], dp[i - 1][j - vw[i - 1][0]] + vw[i - 1][1]);
// }
// }
//}
//return dp[n][V];
vector<int> dp(V + 7); // 滚动数组优化
for (int i = 1; i <= n; ++i)
{
for (int j = V; j >= 0 && j - vw[i - 1][0] >= 0; --j)
{
dp[j] = max(dp[j], dp[j - vw[i - 1][0]] + vw[i - 1][1]);
}
}
return dp[V];
}
};
Day19(40分钟全AC)
小易的升级之路_牛客题霸_牛客网
#include <iostream> // day19_1
#include <numeric>
using namespace std;
int mygcd(int a, int b)
{
return b == 0 ? a : mygcd(b, a % b);
}
int main()
{
long long n = 0, x = 0;
while(cin >> n >> x)
{
int tmp = 0;
for(int i = 0; i < n; ++i)
{
cin >> tmp;
if(tmp <= x)
x += tmp;
else
// x += gcd(x, tmp); // 库里有这个函数或者__gcd
x += mygcd(x, tmp);
}
cout << x << endl;
}
return 0;
}
礼物的最大价值_牛客题霸_牛客网
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param grid int整型vector<vector<>>
* @return int整型
**/
int maxValue(vector<vector<int> >& grid) { // Day19_2
int m = grid.size(), n = grid[0].size();
vector<vector<int>> dp(m + 1, vector<int>(n + 1));
for(int i = 1; i <= m; ++i)
{
for(int j = 1; j <= n; ++j)
{
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
}
}
return dp[m][n];
}
};
对称之美 (nowcoder.com)
// 可以用哈希表优化
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
int T = 0;
cin >> T;
while(T--)
{
int n = 0;
cin >> n;
vector<string> vStr(n);
for(int i = 0; i < n; ++i)
{
cin >> vStr[i];
}
// 枚举最左边的每一个字符,和最右边的每一个字符相比,有一样的就是true
int left = 0, right = n - 1;
while(left < right)
{
bool flag = false;
for(auto& e1 : vStr[left])
{
for(auto& e2 : vStr[right])
{
if(e1 == e2)
{
flag = true;
break;
}
}
if(flag)
break;
}
if(!flag)
{
cout << "No" << endl;
break;
}
++left;
--right;
}
if(left >= right)
cout << "Yes" << endl;
}
return 0;
}
Day20_第三题最长非回文字符串不会
经此一役小红所向无敌 (nowcoder.com)
法一直接模拟:(理论超时但没超时)
#include <iostream> // Day20_1
using namespace std;
int main()
{
int a = 0, h = 0, b = 0, k = 0;
cin >> a >> h >> b >> k;
long long res = 0;
while(h > 0 && k > 0)
{
res += a + b;
h -= b;
k -= a;
}
res += h > 0 ? a * 10 : 0;
res += k > 0 ? b * 10 : 0;
cout << res << endl;
return 0;
}
法二:数学直接计算;
#include <iostream> // Day20_1
#include <cmath>
using namespace std;
int main()
{
long long a = 0, h = 0, b = 0, k = 0;
cin >> a >> h >> b >> k;
long long res = 0, n = min(h / b, k / a); // 结果和回合数
res += n * (a + b);
h -= n * b; // 计算剩余血量
k -= n * a;
if(h > 0 && k > 0) // 判断是否都还活着
{
h -= b;
k -= a;
res += a + b;
}
if(h > 0 || k > 0)
res += (h > 0 ? a * 10 : b * 10);
cout << res << endl;
return 0;
}
连续子数组最大和_牛客题霸_牛客网
#include <iostream> // Day20_2
#include <vector>
using namespace std;
int main()
{
int n = 0;
cin >> n;
vector<int> a(n);
for(int i = 0; i < n; ++i)
{
cin >> a[i];
}
vector<int> dp(n);
int res = a[0];
dp[0] = a[0];
for(int i = 1; i < n; ++i)
{
dp[i] = max(dp[i - 1] + a[i], a[i]);
res = max(res, dp[i]);
}
cout << res << endl;
return 0;
}
非对称之美 (nowcoder.com)
最长非回文字符串(判断是否全同->0,否则是n-1(回文减去1)或n)
#include <iostream>
using namespace std;
int main() // (判断是否全同->0,否则是n-1(回文减去1)或n)
{
string str;
cin >> str;
int sz = str.size();
bool flag = true;
for(int i = 0; i < sz; ++i)
{
if(str[i] != str[0]) // 判断是否全同
{
flag = false;
}
}
if(flag)
{
cout << 0 << endl;
return 0;
}
int left = 0, right = sz - 1;
flag = true; // 判断整个串是否是回文串
while(left < right)
{
if(str[left] != str[right])
{
flag = false;
break;
}
++left;
--right;
}
if(flag)
cout << sz - 1<< endl;
else
cout << sz << endl;
return 0;
/*
string str;
cin >> str;
int sz = str.size(), res = 1;
for(int i = 0; i < sz; ++i)
{
int left = i, right = sz - 1;
while(left < right)
{
if(str[left] != str[right])
break;
--right;
}
// cout << right - left + 1 << endl;
res = max(res, right - left + 1);
}
cout << res;
// eeeeemeeeee处理不了
return 0;
*/
}
Day21(25分钟全AC,虽然提前看了回文串dp)
爱丽丝的人偶 (nowcoder.com)
#include <iostream>
using namespace std;
int main()
{
int n = 0;
cin >> n;
int k = n / 2, left = 1, right = n;
while(k--)
{
cout << left++ << " " << right-- << " ";
}
if(n % 2 != 0)
{
cout << n / 2 + 1;
}
return 0;
}
集合_牛客题霸_牛客网 (nowcoder.com)
#include <iostream>
#include <set>
using namespace std;
int main()
{
int n = 0, m = 0;
cin >> n >> m;
set<int> s;
int tmp = 0;
while(n--)
{
cin >> tmp;
s.insert(tmp);
}
while(m--)
{
cin >> tmp;
s.insert(tmp);
}
auto it = s.begin();
while(it != s.end())
{
cout << *it << " ";
++it;
}
return 0;
}
最长回文子序列_牛客题霸_牛客网 (nowcoder.com)
#include <iostream>
#include <vector>
using namespace std;
int main()
{
string str;
cin >> str;
int n = str.size();
vector<vector<int>> dp(n, vector<int>(n));
// dp[i][j] 表示i到j区间的最长回文子序列
for(int i = n - 1; i >= 0; --i)
{
dp[i][i] = 1;
for(int j = i + 1; j < n; ++j)
{
if(str[i] == str[j])
dp[i][j] = dp[i + 1][j - 1] + 2;
else
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
}
}
cout << dp[0][n - 1];
return 0;
}
Day22(全AC,第三题背包有点没懂)
添加字符_牛客笔试题_牛客网
#include <climits>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() // Day22_1
{
string str1, str2;
cin >> str1 >> str2;
int n1 = str1.size(), n2 = str2.size();
int res = INT_MAX;
for(int i = 0; i < n2 - n1 + 1; ++i) // 枚举str2每一位
{
int cnt = 0;
for(int j = 0; j < n1; ++j) // 枚举str1每一位
{
if(str2[i + j] != str1[j])
++cnt;
}
// cout << "i " << i << endl;
// cout << "cnt " << cnt << endl;
res = min(res, cnt);
}
cout << res << endl;
return 0;
// string str1, str2;
// cin >> str1 >> str2;
// vector<int> hash(26); // 错的,用str1依次和str2中间的比?
// for(auto& e : str2)
// {
// hash[e - 'a']++;
// }
// int res = 0;
// for(auto& e : str1)
// {
// if(hash[e - 'a'] == 0)
// ++res;
// else
// --hash[e - 'a'];
// }
// cout << res << endl;
// return 0;
}
数组变换__牛客网
原暴力AC代码:
#include <iostream>
#include <vector>
using namespace std;
int main() // Day22_2
{
int n = 0, aMax = 0;
cin >> n;
vector<int> a(n);
for(int i = 0 ; i < n; ++i)
{
cin >> a[i];
aMax = max(aMax, a[i]);
}
for(int i = 0 ; i < n; ++i)
{
while(a[i] < aMax)
{
a[i] *= 2;
}
if(a[i] > aMax)
{
cout << "NO" << endl;
return 0;
}
}
cout << "YES" << endl;
return 0;
}
位运算代码:
#include <iostream>
#include <vector>
using namespace std;
int main() // Day22_2
{
int n = 0, aMax = 0;
cin >> n;
vector<int> a(n);
for(int i = 0; i < n; ++i)
{
cin >> a[i];
aMax = max(aMax, a[i]);
}
for(int i = 0 ; i < n; ++i)
{
// while(a[i] < aMax)
// {
// a[i] *= 2;
// }
// if(a[i] > aMax)
if((aMax % a[i]) || a[i] != 1 && a[i] < aMax && a[i] & (a[i] - 1) != 0)
{
cout << "NO" << endl;
return 0;
}
}
cout << "YES" << endl;
return 0;
}
第三题01背包的正确解法(自己写的啥)
登录—专业IT笔试面试备考平台_牛客网
自己碰巧AC的代码
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int main()
{
int V = 0, n = 0;
cin >> V >> n;
vector<int> arr(n);
for(int i = 0; i < n; ++i)
{
cin >> arr[i];
}
vector<vector<int>> dp(n + 1, vector<int>(V + 1));
// dp[i][j] 表示0到i个箱子所选择到的最大体积j
// 选i if(j + arr[i] < V)dp[i][j] = dp[i - 1][j + arr[i]] + arr[i]
// 不选i dp[i][j] = dp[i - 1][j]
// 注意找原数组下标-1
for(int i = 1; i <= n; ++i)
{
for(int j = V; j >= 0; --j)
{
dp[i][j] = dp[i - 1][j];
if(j + arr[i - 1] <= V)
dp[i][j] = max(dp[i][j], dp[i - 1][j + arr[i - 1]] + arr[i - 1]);
// cout << dp[i][j] << endl;
// res = min(res, V - dp[i][j]);
}
}
cout << V - dp[n][0] << endl;
return 0;
}
正解代码
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int main()
{
int V = 0, n = 0;
cin >> V >> n;
vector<int> arr(n); // 下面找原数组不-1的话就多开一个位置占位,输入[1,n]
for(int i = 0; i < n; ++i)
{
cin >> arr[i];
}
vector<vector<int>> dp(n + 1, vector<int>(V + 1));
for(int i = 1; i <= n; ++i)
{
for(int j = 0; j <= V; ++j)
{
dp[i][j] = dp[i - 1][j];
if(j >= arr[i - 1])
dp[i][j] = max(dp[i][j], dp[i - 1][j - arr[i - 1]] + arr[i - 1]);
}
}
cout << V - dp[n][V] << endl;
return 0;
}
Day23
打怪(没用到数学)
打怪 (nowcoder.com)
#include <iostream> // Day23_1,示例感觉都错了,还是没看懂,后面看懂了
using namespace std;
int main()
{
int t = 0;
cin >> t;
while(t--)
{
int h = 0, a = 0, H = 0, A = 0;
cin >> h >> a >> H >> A; // 血量攻击力 血量攻击力
int res = 0;
int tmp = H;
while(h > 0)
{
// cout << h << " " << a << " " << tmp << " " << A << " res " << res << endl;
if(A <= 0 || H <= a)
{
res = -1;
break;
}
if(a <= 0)
{
res = 0;
break;
}
tmp -= a;
if(tmp <= 0)
{
++res;
tmp = H;
continue;
}
h -= A;
}
cout << res << endl;
}
return 0;
}
字符串分类(3/30)脑子瓦特了没想到排序
字符串分类_牛客笔试题_牛客网
#include <iostream>
#include <unordered_set>
#include <algorithm>
using namespace std;
int main()
{
int n = 0;
cin >> n;
string str;
unordered_set<string> res;
while(n--)
{
cin >> str;
sort(str.begin(), str.end());
res.insert(str);
}
cout << res.size() << endl;
return 0;
}
城市群数量(用的并查集,视频给的dfs解决联通快的解法)23上午
城市群数量_牛客题霸_牛客网 (nowcoder.com)
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param m int整型vector<vector<>>
* @return int整型
*/
int citys(vector<vector<int> >& m) {
int n1 = m.size(), n2= m[0].size();
vector<int> arr(n1, -1);
auto findRoot = [&](int x)
{
while(arr[x] != -1)
{
x = arr[x];
}
return x;
};
for(int i = 0; i < n1; ++i)
{
for(int j = 0; j < n2; ++j)
{
if(m[i][j] == 1)
{
int x1 = findRoot(i);
int x2 = findRoot(j);
if(x1 != x2) // x2合到x1
{
arr[x1] = arr[x2]; // 写OJ时少了这句,但也能过
arr[x2] = x1;
}
}
}
}
int res = 0;
for(auto& e : arr)
{
if(e == -1)
++res;
}
return res;
}
};
Day_24
JZ79判断是不是平衡二叉树
判断是不是平衡二叉树_牛客题霸_牛客网
class Solution { // Day_24_1
public:
bool IsBalanced_Solution(TreeNode* pRoot) {
return dfs2(pRoot) != -1;
}
int dfs(TreeNode* pRoot) // 返回-1代表不是平衡二叉树,不返回-1的话返回的是树高
{
if(pRoot == nullptr)
return 0;
if(pRoot->left == nullptr && pRoot->right == nullptr)
return 1;
if(abs(dfs(pRoot->left) - dfs(pRoot->right)) > 1)
return -1;
if(dfs(pRoot->left) != -1 && dfs(pRoot->right) != -1)
return max(dfs(pRoot->left), dfs(pRoot->right)) + 1;
return -1;
}
int dfs2(TreeNode* pRoot) // 题解代码。返回-1代表不是平衡二叉树,不返回-1的话返回的是树高
{
if(pRoot == nullptr)
return 0;
int left = dfs(pRoot->left);
if(left == -1) // 剪枝
return -1;
int right = dfs(pRoot->right);
if(right == -1)
return -1;
return abs(left - right) <= 1 ? max(left, right) + 1 : -1;
}
};
/*
class Solution { // Day_24_1
public:
bool IsBalanced_Solution(TreeNode* pRoot) {
if(pRoot == nullptr)
return true;
if(abs(rootHight(pRoot->left) - rootHight(pRoot->right)) > 1)
return false;
return IsBalanced_Solution(pRoot->left) && IsBalanced_Solution(pRoot->right);
}
int rootHight(TreeNode* pRoot)
{
if(pRoot == nullptr)
return 0;
if(pRoot->left == nullptr && pRoot->right == nullptr)
return 1;
return max(rootHight(pRoot->left), rootHight(pRoot->right)) + 1;
}
};
*/
DP10最大子矩阵(前缀和_最后一步的公式忘想了。。)
最大子矩阵_牛客题霸_牛客网 (nowcoder.com)
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
#define int long long
signed main() // Day24_2 前缀和,然后枚举两个点
{
int n = 0;
cin >> n;
vector<vector<int>> vv(n, vector<int>(n));
int res = INT_MIN;
for(int i = 0; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
cin >> vv[i][j];
res = max(res, vv[i][j]);
}
}
vector<vector<int>> preSum(n + 1, vector<int>(n + 1));
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= n; ++j)
{
preSum[i][j] = preSum[i - 1][j] + preSum[i][j - 1] - preSum[i - 1][j - 1] + vv[i - 1][j - 1];
}
}
// for(int i = 1; i <= n; ++i)
// {
// for(int j = 1; j <= n; ++j)
// {
// cout << preSum[i][j] << " ";
// }
// cout << endl;
// }
for(int i = 1; i <= n; ++i) // 下次用x1,y1, x2,y2
{
for(int j = 1; j <= n; ++j)
{
for(int ii = 1; ii <= i; ++ii)
{
for(int jj = 1; jj <= j; ++jj)
{
res = max(res, preSum[i][j] - preSum[i][jj - 1] - preSum[ii - 1][j] + preSum[ii - 1][jj - 1]); // 注意-1
// cout << i << j << " " << ii << jj << endl;
}
}
}
}
cout << res << endl;
return 0;
}
/*
0 -2 -7 0
9 9 -4 -2
-4 6 -2 -3
-1 13 11 6
9
0 -2 -9 -9
9 9 -4 -2
5 6 -11 -8
4 13 -4 -3
15
*/
小葱的01串(上一题写的有点久,脑子不够用了,没想到用什么算法,以为是dp,其实是滑动窗口)
小葱的01串 (nowcoder.com)
#include <iostream>
using namespace std;
int main() // Day24_3_在连续区间中找个数为一半1的1和一半0的0?的区间的数目
{
int n = 0, res = 0;
string str;
cin >> n >> str;
int cnt0 = 0, cnt1 = 0;
for(int i = 0; i < n; ++i)
{
if(str[i] == '0')
++cnt0;
else
++cnt1;
}
if(cnt0 % 2 != 0 || cnt1 % 2 != 0)
{
cout << 0 << endl;
return 0;
}
cnt0 /= 2, cnt1 /= 2;
int left = 0, right = 0;
int tmp0 = 0, tmp1 = 0;
while(right < n - 1)
{
if(str[right] == '0')
++tmp0;
else
++tmp1;
while(right - left + 1 > n / 2) // 下面注释的出窗口逻辑错了
{
if(str[left++] == '0')
--tmp0;
else
--tmp1;
}
if(right - left + 1 == n / 2) // 注释掉也行,但有点怪
{
if(tmp0 == cnt0 && tmp1 == cnt1)
res += 2;
}
++right;
}
/*
while(right < n - 1)
{
if(str[right] == '0')
++tmp0;
else
++tmp1;
while(left < n && right - left + 1 == n / 2 && tmp0 == cnt0 && tmp1 == cnt1)
{
//cout << tmp0 << " " << tmp1 << endl;
//cout << left << " " << right << endl;
res += 2;
if(str[left++] == '0')
--tmp0;
else
--tmp1;
}
++right;
}
*/
cout << res << endl;
return 0;
}