思路和代码仅供参考
填空题
一、质因数
【问题描述】
如果一个数 p 是个质数,同时又是整数 a 的约数,则 p 称为 a 的一个质因数。请问, 2024 的最大的质因数是多少?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
● 答案 23
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
bool isprime(int x)
{
if (x < 2)
return false;
for (int i = 2; i < sqrt(x); i++)
{
if (x % i == 0)
return false;
}
return true;
}
int main()
{
int n = 2024;
for (int i = n; i >= 0; i--)
{
if (isprime(i) && n % i == 0)
{
cout << i << endl;
break;
}
}
return 0;
}
二、LCM
【问题描述】
对于两个整数 a, b,既是 a 的整数倍又是 b 的整数倍的数称为 a 和 b 的公倍数。公倍数中最小的正整数称为 a 和 b 的最小公倍数。请问, 2024 和 1024 的最小公倍数是多少?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
● 答案259072
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
int gcd(int a, int b)
{
while (b != 0)
{
a %= b;
swap(a, b);
}
return a;
}
int lcm(int a, int b)
{
return (a * b) / gcd(a, b);
}
int main()
{
int n = 2024, m = 1024;
cout << lcm(m, n);
return 0;
}
三、质因数
【问题描述】
如果一个数 p 是个质数,同时又是整数 a 的约数,则 p 称为 a 的一个质因数。请问, 2024 的所有质因数的和是多少?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
● 答案 36
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
bool isprime(int x)
{
if (x < 2)
return false;
for (int i = 2; i <= sqrt(x); i++)
{
if (x % i == 0)
return false;
}
return true;
}
int main()
{
int n = 2024;
int ans = 0;
for (int i = n; i > 0; i--)
{
if (isprime(i) && n % i == 0)
{
ans += i;
cout << i << endl;
}
}
cout << ans << endl;
return 0;
}
四、质数
【问题描述】
请问,在不超过 2024 的数中,最大的质数是多少?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
● 答案 2017
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
bool isprime(int x)
{
if (x < 2)
return false;
for (int i = 2; i <= sqrt(x); i++)
{
if (x % i == 0)
return false;
}
return true;
}
int main()
{
int n = 2024;
for (int i = n; i > 0; i--)
{
if (isprime(i))
{
cout << i << endl;
break;
}
}
return 0;
}
五、互质
【问题描述】
如果两个整数 a, b 除了 1 以外,没有其它的公约数,则称整数 a 与 b 互质。请问,与 2024 互质的数中(包括1),第 2024 小的数是多少?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
● 答案4655
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
vector<int> v;
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int main()
{
int n = 2024;
int cnt = 1;
for (int i = 1;; i++)
{
if (cnt == 2025)
break;
if (gcd(i, n) == 1)
{
v.push_back(i);
cout << "第" << cnt << "次的数为 " << i << endl;
cnt++;
}
}
return 0;
}
六、找子串
【问题描述】
对于字符串 S=ANQNANBNQNANQNQNBNINQNQNANQNINANQNANBNQNANQNQNBNBNQNQNANQNINANQNANBNQNANQNQNBNINQNQNANQNINBNQNANBNQN ,请找到 S 的一个长度不超过 10 的子串 A,使得(A的长度)乘以(A在S中出现的次数)最大。请问这个子串是什么?(如果有多个满足条件的,请回答字典序最小的)。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个字符串,在提交答案时只填写这个字符串,填写多余的内容将无法得分。
● 答案
NQN
69
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
// 滑动窗口枚举所有长度不超过10的子串
vector<string> findsubstring(string text)
{
int n = text.length();
string cursubstr;
vector<string> substrs;
for (int len = 1; len <= n && len <= 10; len++)
{
for (int i = 0; i <= n - len; i++)
{
cursubstr = text.substr(i, len);
substrs.push_back(cursubstr);
}
}
return substrs;
}
//
int findsubstringcount(string text, string pattern)
{
int m = text.length();
int n = pattern.length();
int count = 0;
for (int i = 0; i <= m - n; i++)
{
bool match = true;
for (int j = 0; j < n; j++)
{
if (text[i + j] != pattern[j])
{
match = false;
break;
}
}
if (match)
count++; // 匹配成功,计数器加 1
}
return count;
}
int main()
{
string test = "ANQNANBNQNANQNQNBNINQNQNANQNINANQNANBNQNANQNQNBNBNQNQNANQNINANQNANBNQNANQNQNBNINQNQNANQNINBNQNANBNQN";
vector<string> v = findsubstring(test);
vector<int> v1;
vector<string> ans;
for (const string &s : v)
{
int count = findsubstringcount(test, s);
int multi = s.length() * count;
/*最大的数
if (multi == 69)
{
cout << "找到了" << endl;
cout << s << endl;
cout << count << endl;
cout << multi << endl;
}
*/
}
return 0;
}
七、指数级枚举(DFS)
【问题描述】
如果一个字符串中只包含字符 0 和字符 1,则称为一个 01 串(包含全为 0 的串和全为 1 的串)。请问有多少个长度为 24 的 01 串,满足任意 5 个连续的位置中不超过 3 个位置的值为 1 。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
● 答案 162165
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
std::vector<int> pos; // 1的位置
void dfs(int begin)
{
if (begin == 25)
{
ans++;
return;
}
if (pos.size() < 2 || begin - pos[pos.size() - 2] > 4)
{
pos.push_back(begin); // 1
dfs(begin + 1);
pos.pop_back();
}
dfs(begin + 1); // 0
}
int main()
{
IOS;
int ans = 0;
dfs(1);
out << ans << endl;
return 0;
}
代码题
一、数学
【问题描述】
小蓝种了一块玉米地,玉米地长 n 米,宽 m 米,每平方米产玉米 a 千克。请问小蓝的玉米地一共能产多少千克玉米?
【输入格式】
输入三行。第一行包含一个正整数 n ,第二行包含一个正整数 m ,第三行包含一个正整数 a 。
【输出格式】
输出一行,包含一个整数,表示答案。
【样例输入】
20 24 900
【样例输出】
432000
【评测用例规模与约定】
对于所有评测用例,1 <= n <= 1000, 1 <= m <= 1000, 1 <= a <= 2000。
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
int main()
{
IOS;
int n, m, a;
cin >> n >> m >> a;
cout << n * m * a << endl;
return 0;
}
二、贪心
【问题描述】
小蓝有一个数组 a[1], a[2], …, a[n], 一个“再创新高”的位置是指一个位置 p ,a[p] 的值比之前每个位置的值都大。请求出小蓝的数组中有多少个再创新高的位置。
【输入格式】
输入的第一行包含一个整数 n 。第二行包含 n 个整数,相邻数之间使用一个空格分隔,依次表示 a[1], a[2], …, a[n] 。
【输出格式】
输出一行,包含一个整数,表示答案。
【样例输入】
8
1 2 3 4 5 6 6 6
【样例输出】
6
【样例输入】
9
3 2 1 6 5 4 9 8 7
【样例输出】
3
【评测用例规模与约定】
对于 30% 的评测用例,1 <= n <= 100,0 <= a[i] <= 1000。
对于 60% 的评测用例,1 <= n <= 1000,0 <= a[i] <= 1000。
对于所有评测用例,1 <= n <= 10000,0 <= a[i] <= 1000000。
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
const int N = 1e6;
int a[N];
int main()
{
IOS;
int n;
cin >> n;
int ans = 0;
int maxx = INT_MIN;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
for (int i = 1; i <= n; i++)
{
if (a[i] > maxx)
{
ans++;
maxx = a[i];
}
}
cout << ans << endl;
return 0;
}
三、排序串
【问题描述】
给定四个字符串 a, b, c, d,请将这四个字符串按照任意顺序依次连接拼成一个字符串。请问拼成的字符串字典序最小是多少?
【输入格式】
输入四行,每行包含一个字符串。
【输出格式】
输出一行包含一个字符串,表示答案。
【样例输入】
LAN LAN QIAO BEI
【样例输出】
BEILANLANQIAO
【评测用例规模与约定】
对于所有评测用例,输入的字符串非空串,由大写字母组成,长度不超过 1000 。
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
bool cmp(const string& a,const string& b) {
return a + b < b + a;
}
int main()
{
IOS;
string a, b, c, d;
cin >> a >> b >> c >> d;
vector<string> words = {a, b, c, d};
sort(words.begin(), words.end(),cmp);
for (int i = 0; i < words.size(); i++)
{
cout << words[i];
}
return 0;
}
四、模拟
【问题描述】
蓝桥村正在给村民们发放礼物。礼物通过一个礼物发放机完成。村民们在机器前排着队领取礼物。每个礼物有一个价值 v[i] ,有的高,有的低。每位村民有自己对于礼物的期望值 e[i] 。礼物发放机每次会显示一个礼物,
如果礼物的价值大于等于村民的期望值,村民就会高兴地把礼物拿走,并离开礼物发放机。
如果礼物的价值比村民的期望值低,村民会让这个礼物取消,并让礼物发放机显示下一个礼物,并重新检查是否满足期望。
村民会重复让礼物发放机显示下⼀个礼物,直到礼物发放机没有更多可以显示的礼物或礼物的价值大于等于自己的期望值。
如果礼物发放机中的所有礼物都显示完了,那么还没领到礼物的村民就无法领取礼物了。
如果所有的村民都领到了礼物,而礼物发放机还有礼物显示,村民们也不会再领取礼物。
现在,小蓝知道了每位村民的期望值,也知道了礼物发放机上礼物的显示顺序,请问总共有多少村民拿到了礼物?
【输入格式】
输入的第一行包含一个整数 n ,表示村民的个数。
第二行包含 n 个整数,相邻数之间使用一个空格分隔,依次表示排队的每位村民的期望值 e[i] 。
第三行包含一个整数 m ,表示礼物发放机会显示的礼物个数。
第四行包含 m 个整数,相邻数之间使用一个空格分隔,依次表示礼物发放机显示的礼物的价值 v[i] 。
【输出格式】
输出一行,包含一个整数,表示答案。
【样例输入】
6
6 5 5 3 6 0
9
9 9 8 2 4 4 3 5 3
【样例输出】
4
【样例说明】
前 4 位村民依次取到了第 1, 2, 3, 5 件礼物。后面的礼物未能满足第 5 位村民。
【评测用例规模与约定】
对于 30% 的评测用例,1 <= n, m <= 20 , 0 <= e[i], v[i] <= 100 。
对于 60% 的评测用例,1 <= n, m <= 300 , 0 <= e[i], v[i] <= 10000 。
对于所有评测用例,1 <= n, m <= 10000 , 0 <= e[i], v[i] <= 1000000 。
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using ll = long long;
vector<ll> e;
vector<ll> v;
int m;
int n;
int main()
{
IOS;
cin >> n >> m;
for (int i = 0; i < n; i++)
{
ll tmp;
cin >> tmp;
e.push_back(tmp);
}
for (int i = 0; i < m; i++)
{
ll tmp;
cin >> tmp;
v.push_back(tmp);
}
int ans = 0;
for (int i = 0; i < e.size(); i++)
{
for (int j = 0; j < v.size(); j++)
{
if (v[j] >= e[i])
{
ans++; // 拿走礼物
v.erase(v.begin() + j); // 删除第j个元素
e.erase(e.begin() + i); // 删除第i个元素
i--;
break;
}
else
{
continue;
}
}
}
cout << ans << endl;
return 0;
}
五、前缀和
【问题描述】
小蓝有一个 n 行 m 列的矩阵 a[i][j] ,他想着矩阵中找出一个“十”字形状的区域,使得区域内的值的和最大。一个“十”字形状的区域可以由两个行号 r1 、 r2 和两个列号 c1 、 c2 表示。“十”字的区域内包括第 r1 行到 r2 行的所有元素,以及第 c1 列到 c2 列的所有元素,既不在这几行也不在这几列的元素不在区域内。为了保证是一个“十”字的形状,必须满足 1 < r1 <= r2 < n,1 < c1 <= c2 < m。
【输入格式】
输入的第一行包含两个整数 n, m ,分别表示行数和列数。接下来 n 行,每行包含 m 个整数,相邻数之间使用一个空格分隔,依次表示矩阵的每行每列的值,本部分的第 i 行第 j 列表示 a[i][j] 。
【输出格式】
输出一行包含一个整数,表示最大的和。
【样例输入】
5 61 -1 2 -2 3 -3-1 2 -2 3 -3 42 -2 3 -3 4 -4-2 3 -3 4 -4 53 -3 4 -4 5 -5
【样例输出】
14
【样例说明】
有两种方法可以得到最大的和。
第一种是取 r1=2, r2=4, c1=3, c2=5,
第二种是取 r1=2, r2=4, c1=5, c2=5 。
【评测用例规模与约定】
对于 30% 的评测用例,3 <= n, m <= 30 ,-1000 <= a[i][j] <= 1000 。
对于 60% 的评测用例,3 <= n, m <= 100 ,-1000 <= a[i][j] <= 1000 。
对于所有评测用例,3 <= n <= 100, 3 <= m <= 5000 ,-1000 <= a[i][j] <= 1000 。
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
const int MIN = -1e9;
const int MAXN = 105;
const int MAXM = 5005;
int mp[MAXN][MAXM];
int prefix[MAXN][MAXM];
int mpp[MAXM];
int ans = MIN;
int n, m;
void initialize()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> mp[i][j];
}
}
for (int i = 0; i <= n; i++)
{
prefix[i][0] = 0;
}
for (int j = 0; j <= m; j++)
{
prefix[0][j] = 0;
}
}
void calprefix()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
prefix[i][j] = mp[i][j] +
prefix[i - 1][j] +
prefix[i][j - 1] -
prefix[i - 1][j - 1];
}
}
}
void solve()
{
for (int r1 = 2; r1 < n; r1++)
{
for (int r2 = r1; r2 < n; r2++)
{
int x = prefix[r2][m] - prefix[r1 - 1][m];
for (int ind = 1; ind <= m; ind++)
{
mpp[ind] = prefix[n][ind] - (prefix[r2][ind] - prefix[r1 - 1][ind]);
}
int minn = 0;
int res = MIN;
for (int i = 1; i <= m; i++)
{
res = max(res, mpp[i] - minn);
minn = min(minn, mpp[i]);
}
ans = max(ans, res + x);
}
}
cout << ans << endl;
}
int main()
{
IOS;
cin >> n >> m;
initialize();
calprefix();
solve();
return 0;
}