临时题解
该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。
弹跳
#include <bits/stdc++.h>
using namespace std;
long long x, y, ans;
int main()
{
freopen("jump.in","r",stdin);
freopen("jump.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> x >> y;
ans = x;
while (x)
{
ans += x / y * 2;
x /= y;
}
cout << ans;
return 0;
}
闰年天数求和
#include <bits/stdc++.h>
using namespace std;
int l, r, ans;
bool leap(int y)
{
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
return true;
return false;
}
int main()
{
freopen("leap.in","r",stdin);
freopen("leap.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> l >> r;
ans = 0;
for (int i = l; i <= r; i++)
if (leap(i))
ans += 366;
cout << ans;
return 0;
}
文件IO检测
#include <bits/stdc++.h>
using namespace std;
string s, a, b, A, B;
int main()
{
freopen("file.in","r",stdin);
freopen("file.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> s >> a >> b;
A = "freopen(\"" + s + ".in\",\"r\",stdin);";
B = "freopen(\"" + s + ".out\",\"w\",stdout);";
if (a == A && b == B)
cout << "Yes";
else
cout << "No";
return 0;
}
单点修改区间查询青春版
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, q;
int a[100000 + 5];
int sum[100000 + 5];
void initSum()
{
sum[0] = 0;
for (int i = 1; i <= n; i++)
sum[i] = sum[i - 1] + a[i];
}
signed main()
{
freopen("sum.in", "r", stdin);
freopen("sum.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> q;
for (int i = 1; i <= n; i++)
cin >> a[i];
initSum();
while (q--)
{
int op, l, r, x, y;
cin >> op;
if (op == 1)
{
cin >> l >> r;
cout << sum[r] - sum[l - 1] << "\n";
}
if (op == 2)
{
cin >> x >> y;
a[x] = y;
initSum();
}
}
return 0;
}
走走走
https://www.luogu.com.cn/problem/CF2041D
7 15
###############
#S......#E....#
#.###########.#
#.......#.#...#
#######.#.....#
#..#......#...#
###############
30
30 分
#include <bits/stdc++.h>
using namespace std;
int n, m;
string s;
int main()
{
freopen("walk.in", "r", stdin);
freopen("walk.out", "w", stdout);
cin >> n >> m;
cin >> s;
int sPos, ePos;
for (int i = 0; i < s.size(); i++)
if (s[i] == 'S')
sPos = i;
else if (s[i] == 'E')
ePos = i;
for (int i = sPos + 1; i <= ePos - 1; i++)
if (s[i] == '#')
{
cout << "-1";
return 0;
}
// 转换为 1->len
int len = ePos - sPos + 1;
int now = 1; // 当前位置
int cnt = 0; // 连续向右的步骤
int ans = 0; // 走的步数
while (now != len)
{
if (cnt != 3)
{
// 往前走
now++;
cnt++;
ans++;
}
else
{
// 后退
now--;
cnt = 0;
ans++;
}
}
cout << ans << "\n";
return 0;
}
满分
#include <bits/stdc++.h>
using namespace std;
int n, m;
// 获取某个二维点和一维点的对应
int getIdx(int x, int y)
{
return (x - 1) * m + y;
}
int getX(int idx)
{
// idx/m 上取整
return (idx + (m - 1)) / m;
}
int getY(int idx)
{
// 转换到 0 开头的体系,% 完后加回来
return (idx - 1) % m + 1;
}
// 地图与四个方向
char s[100000 + 5];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
// 走到 i 这个位置,上一步在 j,沿着 j 方向连续走了 k 步,目前一共走了几步
int dis[100000 + 5][4][4];
struct Node
{
int idx; // 点的编号
int fx; // 上一步方向
int len; // fx 方向目前连续走的步数
};
queue<Node> q;
int main()
{
freopen("walk.in","r",stdin);
freopen("walk.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
int sPos, ePos;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
int idx = getIdx(i, j);
cin >> s[idx];
if (s[idx] == 'S')
sPos = idx;
if (s[idx] == 'E')
ePos = idx;
}
}
// 起点入队,看作是 0 方向连续走了 0 步到达
// 步数从 1 开始,这样步数为 0 的就是没走过的
dis[sPos][0][0] = 1;
q.push({sPos, 0, 0});
while (!q.empty())
{
Node now = q.front();
q.pop();
int x = getX(now.idx); // 当前点
int y = getY(now.idx); // 当前点
int fx = now.fx; // 当前点
int len = now.len; // 当前点
if (now.idx == ePos)
{
cout << dis[now.idx][fx][len] - 1;
return 0;
}
for (int i = 0; i < 4; i++)
{
int nx = x + dx[i]; // 下一个点的属性
int ny = y + dy[i]; // 下一个点的属性
int nIdx = getIdx(nx, ny); // 下一个点的属性
int nfx = i; // 下一个点的属性
int nlen = (i == fx) ? (len + 1) : 1; // 下一个点的属性
// 方向一样就多了一步,否则就是第一步
if (nx < 1 || nx > n || ny < 1 || ny > m ||
nlen == 4 ||
dis[nIdx][nfx][nlen] != 0 ||
s[nIdx] == '#')
continue;
dis[nIdx][nfx][nlen] = dis[now.idx][now.fx][now.len] + 1;
q.push({nIdx, nfx, nlen});
}
}
cout << -1 << "\n";
return 0;
}
三四五
#include <bits/stdc++.h>
using namespace std;
void work()
{
long long a, aa;
cin >> a;
aa = a;
if (a <= 2)
{
// 特判
cout << -1 << "\n";
return;
}
if (a % 2 == 1)
{
// 判断奇数
a *= a;
cout << aa << " ";
cout << (a - 1) / 2 << " ";
cout << (a + 1) / 2 << "\n";
}
if (a % 2 == 0)
{
// 判断偶数
int ans = 1;
while (a % 2 == 0)
{
a /= 2;
ans *= 2;
}
if (a == 1) // 特判二次幂
{
cout << 3 * ans / 4 << " ";
cout << aa << " ";
cout << 5 * ans / 4 << "\n";
return;
}
a *= a;
cout << aa << " ";
cout << (a - 1) * ans / 2 << " ";
cout << (a + 1) * ans / 2 << "\n";
}
}
int main()
{
freopen("three.in", "r", stdin);
freopen("three.out", "w", stdout);
int n;
cin >> n;
while (n--)
work();
return 0;
}
玩游戏
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200000;
int n, m;
set<int> e[MAXN + 5]; // set 存图,方便删点
// 类似拓扑排序不停删入度为 2 的点的队列
int d[MAXN + 5];
queue<int> q;
// 还原时用到的链表
int nxt[MAXN + 5], pre[MAXN + 5];
bool vis[MAXN + 5];
void dfs(int u)
{
cout << u << " ";
vis[u] = true;
int x = nxt[u];
int y = pre[u];
if (x > y)
swap(x, y);
if (!vis[x])
dfs(x);
if (!vis[y])
dfs(y);
}
int main()
{
freopen("circle.in", "r", stdin);
freopen("circle.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0);
// 存图
cin >> n >> m;
for (int i = 0; i < m; i++)
{
int u, v;
cin >> u >> v;
if (u == v)
continue;
e[u].insert(v);
e[v].insert(u);
}
// 特判
if (n <= 2)
{
for (int i = 1; i <= n; i++)
cout << i << " ";
return 0;
}
// 计算度数并把入度为 2 的入队
for (int i = 1; i <= n; i++)
{
d[i] = e[i].size();
if (d[i] == 2)
q.push(i);
}
// 按顺序所有删除的点以及左右点
// <度数为 2 的点, <左边的点, 右边的点>>
vector<pair<int, pair<int, int>>> all2;
int nn = n; // 剩余点数,超过两个点就丢一个入度为 2 的
while (nn > 2)
{
int now = q.front();
q.pop();
if (e[now].size() != 2)
continue;
// 取出 now 相连的两个点
int nowL = *(e[now].begin());
e[now].erase(e[now].begin());
int nowR = *(e[now].begin());
e[now].erase(e[now].begin());
// 记住 now 的左右点
all2.push_back({now, {nowL, nowR}});
// 在 nowL,nowR 中移除 now
e[nowL].erase(now);
e[nowR].erase(now);
d[nowL]--;
d[nowR]--;
// 删除 now
e[now].clear();
d[now] = 0;
nn--;
// nowL与nowR 如果之前不相连就连边
if (nowL != nowR && e[nowL].find(nowR) == e[nowL].end())
{
e[nowL].insert(nowR);
e[nowR].insert(nowL);
d[nowL]++;
d[nowR]++;
}
// 检测 nowL,nowR 度数是否删到了 2
if (d[nowL] == 2)
q.push(nowL);
if (d[nowR] == 2)
q.push(nowR);
}
// 从剩余的两个点开始构造方案
int u = -1, v = -1;
for (int i = 1; i <= n; i++)
if (d[i] != 0)
{
if (u == -1)
u = i;
else
v = i;
}
nxt[u] = v, pre[u] = v;
nxt[v] = u, pre[v] = u;
for (int i = (int)all2.size() - 1; i >= 0; --i)
{
int now = all2[i].first;
int nowL = all2[i].second.first;
int nowR = all2[i].second.second;
if (nxt[nowR] == nowL)
swap(nowL, nowR);
// 保证是:nowL ~ nowR
// 下一步:nowL ~ now ~ nowR
if (nxt[nowL] == nowR)
{
nxt[now] = nowR, pre[now] = nowL;
nxt[nowL] = now, pre[nowR] = now;
}
}
dfs(1);
return 0;
}