Upload via code

This commit is contained in:
2024-10-03 19:17:29 +08:00
parent 543ccf0fe0
commit b64d31db74
39 changed files with 1548 additions and 0 deletions

61
FZOI/Tad 蛋糕.cpp Normal file
View File

@ -0,0 +1,61 @@
#include <bits/stdc++.h>
#define int long long
#define endl "\n"
#define IMX LONG_LONG_MAX
#define IMN LONG_LONG_MIN
using namespace std;
/* toothless. #17 */
const int N = 1e7 + 10;
const int M = 2e3 + 5;
int n, m;
int a[1000000];
int qzh[1000000];
int st[1000000][25];
int lg[1000000];
void init()
{
lg[1] = 0;
for (int i = 2; i <= n; i++)
{
lg[i] = lg[i / 2] + 1;
}
for (int i = 1; i <= n; i++)
{
st[i][0] = qzh[i];
}
for (int k = 1; k <= lg[m]; k++)
{
for (int i = 1; i <= n; i++)
{
st[i][k] = max(st[i][k - 1], st[min(i + (1 << (k - 1)), n)][k - 1]);
}
}
}
int quary(int l, int r)
{
int k = lg[r - l + 1];
return max(st[l][k], st[r - (1 << k) + 1][k]);
}
signed main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
qzh[i] = qzh[i - 1] + a[i];
}
int maxl = -INT_MIN;
init();
for (int i = 1; i <= n; i++)
{
int r = min(i + m - 1, n);
int s = quary(i, r) - qzh[i - 1];
maxl = max(maxl, s);
}
cout << maxl;
return 0;
}

View File

@ -0,0 +1,34 @@
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
int n, k;
cin >> n >> k;
vector<int> nums;
for (int i = 0; i < n; ++i)
{
char op;
cin >> op;
if (op == 'I')
{
int num;
cin >> num;
nums.push_back(num);
}
else if (op == 'Q')
{
if (nums.size() >= k)
{
sort(nums.begin(), nums.end(), greater<int>());
cout << nums[k - 1] << endl;
}
}
}
return 0;
}

40
FZOI/grouping.cpp Normal file
View File

@ -0,0 +1,40 @@
#include <bits/stdc++.h>
#define int long long
#define endl "\n"
#define IMX LONG_LONG_MAX
#define IMN LONG_LONG_MIN
using namespace std;
/* toothless. #17 */
const int N = 1e7 + 10;
const int M = 2e3 + 5;
int n, mn = IMX;
int a[N];
signed main()
{
cin >> n;
for (int i = 0; i < n; i ++ )
{
cin >> a[i];
}
sort(a, a + n);
int cnt = 1;
for (int i = 1; i < n; i ++ )
{
if (a[i] == a[i - 1] + 1)
{
cnt ++ ;
}
else
{
mn = min(mn, cnt);
cnt = 1;
}
}
mn = min(mn, cnt);
cout << mn << endl;
return 0;
}

View File

@ -0,0 +1,24 @@
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, k, cnt;
void dfs(int last, int sum, int cur)
{
if (cur == k)
{
if (sum == n)
cnt++;
return;
}
for (int i = last; sum + i * (k - cur) <= n; i++)
dfs(i, sum + i, cur + 1);
}
signed main()
{
cin >> n >> k ;
dfs(1, 0, 0);
cout << cnt ;
}

View File

@ -0,0 +1,59 @@
#include <bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N = 20005;
int n, heap[N], size;
void put(int t)
{
int p1, p2;
heap[ ++ size] = t;
p1 = size;
while(p1 > 1)
{
p2 = p1 / 2;
if(heap[p1] >= heap[p2]) return ;
swap(heap[p1], heap[p2]);
p1 = p2;
}
}
int out()
{
int p = 1, g, ans;
ans = heap[1];
heap[1] = heap[size -- ];
while(p * 2 <= size)
{
g = p * 2;
if(g < size && heap[g + 1] < heap[g]) g ++ ;
if(heap[p] <= heap[g]) return ans;
swap(heap[p], heap[g]);
p = g;
}
return ans;
}
signed main()
{
int ans = 0;
cin >> n ;
for(int i = 1; i <= n; ++ i)
{
int q;
cin >> q ;
put(q);
}
size = n;
while(size > 1)
{
int x = out(), y = out();
ans += (x + y);
put(x + y);
}
cout << ans ;
return 0;
}

29
FZOI/全排列问题.cpp Normal file
View File

@ -0,0 +1,29 @@
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, arr[1030], ans[10];
void dfs(int i, int s)
{
if (i > n)
{
for (int p = 1; p <= n; p++) printf("%5d", ans[p]);
cout << endl;
return;
}
for (int j = s; j > 0; j -= j & (-j))
{
int temp = j & (-j);
ans[i] = arr[temp];
dfs(i + 1, s - temp);
}
}
signed main()
{
cin >> n;
arr[1] = 1;
for (int i = 2; i <= n; i++)
arr[1 << (i - 1)] = i;
dfs(1, (1 << n) - 1);
return 0;
}

56
FZOI/分身术.cpp Normal file
View File

@ -0,0 +1,56 @@
#include <bits/stdc++.h>
#define int long long
#define endl "\n"
#define fp(_a, _b, _c, _d) for (int _a = _b; _a <= _c; _a += _d)
#define fm(_a, _b, _c, _d) for (int _a = _b; _a <= _c; _a -= _d)
#define fin(_a, _b) for (int ss = 1; ss <= _a; ss++) cin >> _b[ss];
#define fout(_a, _b, _c) for (int ss = 1; ss <= _a; ss++) cout << _b[ss] << _c;
using namespace std;
/*
@author: BunDragon126
@link: https://www.setbun.com/
*/
const int N = 1e7 + 10;
const int M = 2e3 + 5;
int n, k;
vector<int> a(N), b(N);
deque<int> deque1, deque2;
signed main()
{
"toothless. #17";
cin >> n >> k;
for (int i = 0; i < n; ++ i) cin >> a[i];
for (int i = 0; i < n; ++ i) cin >> b[i];
int mn = n + 1;
for (int l = 0, r = 0; r < n; ++ r)
{
while (!deque1.empty() && a[deque1.back()] >= a[r])
deque1.pop_back();
deque1.push_back(r);
while (!deque2.empty() && b[deque2.back()] <= b[r])
deque2.pop_back();
deque2.push_back(r);
while (a[deque1.front()] <= k && b[deque2.front()] > a[deque1.front()])
{
mn = min(mn, r - l + 1);
if (deque1.front() == l)
deque1.pop_front();
if (deque2.front() == l)
deque2.pop_front();
++ l;
}
}
if (mn == n + 1)
{
cout << "So Sad!" << endl;
}
else
{
cout << mn << endl;
}
return 0;
}

56
FZOI/四色问题.cpp Normal file
View File

@ -0,0 +1,56 @@
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 8;
int n;
int arr[MAXN][MAXN];
int color[MAXN];
int ans;
bool f(int v, int c)
{
for (int i = 0; i < n; i++)
{
if (arr[v][i] && color[i] == c)
{
return false;
}
}
return true;
}
void dfs(int v)
{
if (v == n)
{
ans++;
return;
}
for (int c = 1; c <= 4; c++)
{
if (f(v, c))
{
color[v] = c;
dfs(v + 1);
color[v] = 0;
}
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> arr[i][j];
}
}
memset(color, 0, sizeof(color));
ans = 0;
dfs(0);
cout << ans << endl;
return 0;
}

View File

@ -0,0 +1,57 @@
#include <bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N = 20005;
int n, heap[N], size;
void add(int t)
{
int p1, p2;
heap[ ++ size] = t;
p1 = size;
while(p1 > 1)
{
p2 = p1 / 2;
if(heap[p1] >= heap[p2]) return ;
swap(heap[p1], heap[p2]);
p1 = p2;
}
}
void out()
{
int p = 1, g, ans;
ans = heap[1];
heap[1] = heap[size -- ];
while(p * 2 <= size)
{
g = p * 2;
if(g < size && heap[g + 1] < heap[g]) g ++ ;
if(heap[p] <= heap[g]) return ;
swap(heap[p], heap[g]);
p = g;
}
}
signed main()
{
int ans = 0;
cin >> n ;
for(int i = 1; i <= n; ++ i)
{
int q;
cin >> q ;
if(q == 1)
{
int x;
cin >> x;
add(x);
}
else if(q == 2) cout << heap[1] << endl ;
else out();
}
return 0;
}

28
FZOI/奇怪的电梯.cpp Normal file
View File

@ -0,0 +1,28 @@
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, a, b, k[201], dis[201];
void dfs(int node, int step)
{
dis[node] = step;
int v = node - k[node];
if (1 <= v && step + 1 < dis[v])
dfs(v, step + 1);
v = node + k[node];
if (v <= n && step + 1 < dis[v])
dfs(v, step + 1);
return;
}
signed main()
{
memset(dis, 0x3f, sizeof(dis));
cin >> n >> a >> b;
for (int i = 1; i <= n; i++)
cin >> k[i];
dfs(a, 0);
if(dis[b] == 0x3f3f3f3f3f3f3f3f) cout << -1 << endl;
else cout << dis[b] << endl;
return 0;
}

View File

@ -0,0 +1,36 @@
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 20;
int n;
int arr[MAXN][MAXN];
int mn;
void f()
{
mn = INT_MAX;
for (int i = 0; i < n; i++)
{
int cnt = 0;
for (int j = 0; j < n; j++)
{
cnt += arr[j][i];
}
mn = min(mn, cnt);
}
}
signed main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> arr[i][j];
}
}
f();
cout << mn << endl;
return 0;
}

50
FZOI/括号匹配.cpp Normal file
View File

@ -0,0 +1,50 @@
#include <bits/stdc++.h>
#define int long long
using namespace std;
bool f(const string &s)
{
stack<char> st;
for (char c : s)
{
if (c == '(' || c == '[')
{
st.push(c);
}
else if (c == ')' || c == ']')
{
if (st.empty())
{
return false;
}
char top = st.top();
st.pop();
if ((c == ')' && top != '(') || (c == ']' && top != '['))
{
return false;
}
}
}
return st.empty();
}
signed main()
{
string s;
cin >> s;
if (f(s))
{
cout << "OK" << endl;
}
else
{
cout << "Wrong" << endl;
}
return 0;
}

30
FZOI/数位递增数.cpp Normal file
View File

@ -0,0 +1,30 @@
#include <iostream>
#include <string>
using namespace std;
bool isIncreasingNumber(int n) {
string num = to_string(n);
for (int i = 0; i < num.size() - 1; i++) {
if (num[i] > num[i + 1]) {
return false;
}
}
return true;
}
int main() {
int n;
cin >> n;
int count = 0;
for (int i = 10; i <= n; i++) {
if (isIncreasingNumber(i)) {
count++;
}
}
cout << count << endl;
return 0;
}

63
FZOI/最少步数.cpp Normal file
View File

@ -0,0 +1,63 @@
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 100;
const vector<pair<int, int>> knight_moves = {{2, 1}, {2, -1}, {-2, 1}, {-2, -1}, {1, 2}, {1, -2}, {-1, 2}, {-1, -2}};
const vector<pair<int, int>> elephant_moves = {{2, 2}, {2, -2}, {-2, 2}, {-2, -2}};
int bfs(int start_x, int start_y)
{
vector<vector<bool>> vis(N + 1, vector<bool>(N + 1, false));
queue<tuple<int, int, int>> que;
que.push({start_x, start_y, 0});
vis[start_x][start_y] = true;
while (!que.empty())
{
auto [x, y, steps] = que.front();
que.pop();
if (x == 1 && y == 1)
{
return steps;
}
for (const auto &move : knight_moves)
{
int nx = x + move.first;
int ny = y + move.second;
if (nx >= 1 && nx <= N && ny >= 1 && ny <= N && !vis[nx][ny])
{
vis[nx][ny] = true;
que.push({nx, ny, steps + 1});
}
}
for (const auto &move : elephant_moves)
{
int nx = x + move.first;
int ny = y + move.second;
if (nx >= 1 && nx <= N && ny >= 1 && ny <= N && !vis[nx][ny])
{
vis[nx][ny] = true;
que.push({nx, ny, steps + 1});
}
}
}
return -1;
}
signed main()
{
int x, y, x1, y1;
cin >> x >> y >> x1 >> y1;
int steps_A = bfs(x, y);
int steps_B = bfs(x1, y1);
cout << steps_A << endl;
cout << steps_B << endl;
return 0;
}

80
FZOI/素数环.cpp Normal file
View File

@ -0,0 +1,80 @@
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 16;
int n;
int arr[MAXN];
bool vis[MAXN];
// 判断一个数是否为素数
bool check(int num)
{
if (num < 2)
{
return false;
}
for (int i = 2; i * i <= num; i++)
{
if (num % i == 0)
{
return false;
}
}
return true;
}
// 回溯
// cur表示当前位置
void back(int cur)
{
if (cur == n) // 检查最后一个数字和第一个数字之和是否为素数
{
if (check(arr[0] + arr[n - 1]))
{
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
return;
}
for (int i = 2; i <= n; i++)
{
if (!vis[i] && check(arr[cur - 1] + i))
{
vis[i] = true;
arr[cur] = i;
back(cur + 1);
vis[i] = false;
}
}
}
int main()
{
cin >> n;
memset(vis, false, sizeof(vis));
vis[1] = true;
arr[0] = 1;
back(1);
return 0;
}
/*
以下题解为后期由本人添加
题目分析:
题目要求将整数 1 到 n 组成一个环,使得相邻的两个整数之和均为素数。
我们需要找到所有满足条件的素数环,并按照要求输出。
由于 n 的值不超过 16我们可以使用回溯法来尝试所有可能的组合。
代码解释:
check函数用于判断一个数是否为素数。
back函数是回溯函数用于尝试放置数字到环中。
在back函数中首先判断是否已经放置了 n 个数字。如果是,则检查最后一个数字和第一个数字之和是否为素数。如果是素数,则输出这个环。
然后,从数字 2 到 n 依次尝试将每个数字放在环的下一个位置。如果该数字没有被使用过,并且与前一个数字之和为素数,就将其放在环的下一个位置,并标记为已使用,然后继续递归放置下一个数字。
如果放置过程中出现相邻两个数字之和不是素数的情况,就回溯到上一个数字,重新选择下一个数字。
在main函数中读取输入的 n初始化标记数组和环的第一个数字然后调用back函数从数字 1 开始回溯。
时间复杂度和空间复杂度:
时间复杂度:由于需要尝试所有可能的组合,时间复杂度为 O(n!),其中 n 是输入的数字个数。
空间复杂度:主要是使用了标记数组和环数组,空间复杂度为 O(n)。
*/

43
FZOI/装载问题.cpp Normal file
View File

@ -0,0 +1,43 @@
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 45;
const int MAXC = 2000;
int n, c;
int arr[MAXN];
int dp[MAXN][MAXC];
int f()
{
for (int i = 0; i <= c; i++)
{
dp[0][i] = 0;
}
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= c; j++)
{
if (arr[i - 1] > j)
{
dp[i][j] = dp[i - 1][j];
}
else
{
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - arr[i - 1]] + arr[i - 1]);
}
}
}
return dp[n][c];
}
int main()
{
cin >> n >> c;
for (int i = 0; i < n; i++)
{
cin >> arr[i];
}
cout << f() << endl;
return 0;
}

128
FZOI/非常可乐.cpp Normal file
View File

@ -0,0 +1,128 @@
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int s, n, m, step;
};
bool vis[101][101][101];
int bfs(int s, int n, int m)
{
queue<Node> que;
Node init = {s, 0, 0, 0};
que.push(init);
vis[s][0][0] = true;
while (!que.empty())
{
Node cur = que.front();
que.pop();
if (cur.s == cur.n && cur.s == cur.m)
{
return cur.step;
}
if (cur.s > 0 && cur.n < n)
{
int pour = min(cur.s, n - cur.n);
int newS = cur.s - pour;
int newN = cur.n + pour;
if (!vis[newS][newN][cur.m])
{
vis[newS][newN][cur.m] = true;
Node next = {newS, newN, cur.m, cur.step + 1};
que.push(next);
}
}
if (cur.s > 0 && cur.m < m)
{
int pour = min(cur.s, m - cur.m);
int newS = cur.s - pour;
int newM = cur.m + pour;
if (!vis[newS][cur.n][newM])
{
vis[newS][cur.n][newM] = true;
Node next = {newS, cur.n, newM, cur.step + 1};
que.push(next);
}
}
if (cur.n > 0 && cur.s < s)
{
int pour = min(cur.n, s - cur.s);
int newS = cur.s + pour;
int newN = cur.n - pour;
if (!vis[newS][newN][cur.m])
{
vis[newS][newN][cur.m] = true;
Node next = {newS, newN, cur.m, cur.step + 1};
que.push(next);
}
}
if (cur.n > 0 && cur.m < m)
{
int pour = min(cur.n, m - cur.m);
int newN = cur.n - pour;
int newM = cur.m + pour;
if (!vis[cur.s][newN][newM])
{
vis[cur.s][newN][newM] = true;
Node next = {cur.s, newN, newM, cur.step + 1};
que.push(next);
}
}
if (cur.m > 0 && cur.s < s)
{
int pour = min(cur.m, s - cur.s);
int newS = cur.s + pour;
int newM = cur.m - pour;
if (!vis[newS][cur.n][newM])
{
vis[newS][cur.n][newM] = true;
Node next = {newS, cur.n, newM, cur.step + 1};
que.push(next);
}
}
if (cur.m > 0 && cur.n < n)
{
int pour = min(cur.m, n - cur.n);
int newM = cur.m - pour;
int newN = cur.n + pour;
if (!vis[cur.s][newN][newM])
{
vis[cur.s][newN][newM] = true;
Node next = {cur.s, newN, newM, cur.step + 1};
que.push(next);
}
}
}
return -1;
}
int main()
{
int s, n, m;
while (cin >> s >> n >> m && !(s == 0 && n == 0 && m == 0))
{
memset(vis, false, sizeof(vis));
int res = bfs(s, n, m);
if (res == -1)
{
cout << "NO" << endl;
}
else
{
cout << res << endl;
}
}
return 0;
}