Contest3924 - 计科23级算法设计与分析平时作业-03
题目链接
A.Knight Moves
题面

思路
马的bfs、最短路径问题。模板题
示例代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
//#define int ll
#define pii pair<int, int>
#define all(x) x.begin(),x.end()
#define fer(i, m, n) for(int i = m; i < n; ++i)
#define ferd(i, m, n) for(int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'
const int MOD = 1e9 + 7;
const int N = 2e5 + 2;
const int inf = 1e9;
struct point{
int x, y;
point(int x, int y) : x(x), y(y) {}
};
int dx[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
int dy[8] = {1, 2, 2, 1, -1, -2, -2, -1};
void dfs(string start, string end) {
if(start == end) {
cout << "To get from " << start << " to " << end << " takes " << 0 << " knight moves.\n";
return;
}
queue<point> q;
point start_point(start[0] - 'a', start[1] - '1'), end_point(end[0] - 'a', end[1] - '1');
q.push(start_point);
vector<vector<bool>> vis(8, vector<bool>(8, false));
vis[start_point.x][start_point.y] = true;
vector<vector<int>> dist(8, vector<int>(8, inf));
dist[start_point.x][start_point.y] = 0;
while(!q.empty()) {
point curr = q.front();
q.pop();
if(curr.x == end_point.x && curr.y == end_point.y) {
cout << "To get from " << start << " to " << end << " takes " << dist[curr.x][curr.y] << " knight moves.\n";
return;
}
fer(i, 0, 8){
int nx = curr.x + dx[i], ny = curr.y + dy[i];
auto OnRange = [] (int a, int b) {return a >= 0 && a < 8 && b >= 0 && b < 8;};
if(OnRange(nx, ny) && !vis[nx][ny]) {
if(dist[curr.x][curr.y] + 1 < dist[nx][ny]) {
dist[nx][ny] = dist[curr.x][curr.y] + 1;
q.push({nx, ny});
vis[nx][ny] = true;
}
}
}
}
}
signed main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
string s1, s2;
while(cin >> s1 >> s2) {
dfs(s1, s2);
}
return 0;
}
B.Gold Transportation
题面

示例代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
// #define int ll
#define pii pair<int, int>
#define all(x) x.begin(), x.end()
#define fer(i, m, n) for (int i = m; i < n; ++i)
#define ferd(i, m, n) for (int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'
const int inf = 0x3f3f3f3f;
const int N = 1001, M = 100001;
int head[N], nex[M], to[M], val[M], now;
void add(int a, int b, int v)
{
to[++now] = b;
val[now] = v;
nex[now] = head[a];
head[a] = now;
to[++now] = a;
val[now] = 0;
nex[now] = head[b];
head[b] = now;
}
//*********************
int sp, ep, d[N];
int bfs()
{
queue<int> Q;
memset(d, -1, sizeof(d));
d[sp] = 0;
Q.push(sp);
while (!Q.empty())
{
int p = Q.front();
Q.pop();
for (int i = head[p]; ~i; i = nex[i])
{
int u = to[i];
if (d[u] == -1 && val[i] > 0)
{
d[u] = d[p] + 1;
Q.push(u);
}
}
}
return d[ep] != -1;
}
int dfs(int p, int v)
{
int r = 0;
if (p == ep)
return v;
for (int i = head[p]; (~i) && r < v; i = nex[i])
{
int u = to[i];
if (val[i] > 0 && d[u] == d[p] + 1)
{
int x = dfs(u, min(val[i], v - r));
r += x;
val[i] -= x;
val[i ^ 1] += x;
}
}
if (!r)
d[p] = -2;
return r;
}
int dinic()
{
int ans = 0, t;
while (bfs())
{
while (t = dfs(sp, inf))
ans += t;
}
return ans;
}
//***********************
void init()
{
now = -1; // 要求第一条边为0
memset(head, -1, sizeof(head));
}
int n, m, sum;
int a[M], b[M], v[M];
int s[N], g[N];
int judge(int limit)
{
init();
sp = 0, ep = 201;
for (int i = 1; i <= m; i++)
{
if (v[i] <= limit)
{
add(a[i], b[i], inf);
add(b[i], a[i], inf);
}
}
for (int i = 1; i <= n; i++)
{
if (s[i])
{
add(0, i, s[i]);
}
if (g[i])
{
add(i, 201, g[i]);
}
}
int ans = dinic();
if (ans == sum)
return 1;
return 0;
}
int main()
{
while (scanf("%d", &n) != EOF)
{
if (!n)
break;
sum = 0;
for (int i = 1; i <= n; i++)
scanf("%d", s + i), sum += s[i];
for (int i = 1; i <= n; i++)
scanf("%d", g + i);
scanf("%d", &m);
int l = 0, r = 1e4;
for (int i = 1; i <= m; i++)
scanf("%d%d%d", a + i, b + i, v + i);
if (!judge(1e4))
{
printf("No Solution\n");
continue;
}
if (judge(0))
{
printf("%d\n", 0);
continue;
}
while (r - l > 1)
{
int mid = l + r >> 1;
if (judge(mid))
r = mid;
else
l = mid;
}
printf("%d\n", r);
}
}
C.Function Run Fun
题面

思路
记忆化搜索
示例代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
//#define int ll
#define pii pair<int, int>
#define all(x) x.begin(),x.end()
#define fer(i, m, n) for(int i = m; i < n; ++i)
#define ferd(i, m, n) for(int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'
const int MOD = 1e9 + 7;
const int N = 2e5 + 2;
const int inf = 1e9;
ll memo[100][100][100];
ll w(int a, int b, int c) {
if(a <= 0 || b <= 0 || c <= 0) return 1;
if(memo[a][b][c] != -1) return memo[a][b][c];
if(a > 20 || b > 20 || c > 20)
a = b = c = 20, memo[a][b][c] = w(20, 20, 20);
else if(a < b && b < c)
memo[a][b][c] = w(a, b, c - 1) + w(a, b - 1, c - 1) - w(a, b - 1, c);
else memo[a][b][c] = w(a - 1, b, c) + w(a - 1, b - 1, c) + w(a - 1, b, c - 1) - w(a - 1, b - 1, c - 1);
return memo[a][b][c];
}
signed main() {
//ios::sync_with_stdio(false); cin.tie(nullptr);
int a, b, c;
memset(memo, -1, sizeof(memo));
while(cin >> a >> b >> c) {
if(a == -1 && b == -1 && c == -1) break;
printf("w(%d, %d, %d) = %lld\n", a, b, c, w(a, b, c));
}
return 0;
}
D.Equation Solver
题面

示例代码
#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
using namespace std;
const double EPS = 1e-8;
pair<double, double> parse_expression(const string& s, int& pos);
pair<double, double> parse_term(const string& s, int& pos);
pair<double, double> parse_factor(const string& s, int& pos);
int parse_number(const string& s, int& pos) {
int num = 0;
while (pos < s.size() && isdigit(s[pos])) {
num = num * 10 + (s[pos] - '0');
pos++;
}
return num;
}
pair<double, double> parse_factor(const string& s, int& pos) {
if (s[pos] == 'x') {
pos++;
return {1.0, 0.0};
} else if (isdigit(s[pos])) {
int num = parse_number(s, pos);
return {0.0, (double)num};
} else if (s[pos] == '(') {
pos++;
auto res = parse_expression(s, pos);
if (pos < s.size() && s[pos] == ')') {
pos++;
}
return res;
} else {
return {0.0, 0.0};
}
}
pair<double, double> parse_term(const string& s, int& pos) {
auto res = parse_factor(s, pos);
double a = res.first, b = res.second;
while (pos < s.size() && s[pos] == '*') {
pos++;
auto factor = parse_factor(s, pos);
double new_a = a * factor.second + b * factor.first;
double new_b = b * factor.second;
a = new_a;
b = new_b;
}
return {a, b};
}
pair<double, double> parse_expression(const string& s, int& pos) {
pair<double, double> res = {0.0, 0.0};
bool positive = true;
if (pos < s.size() && (s[pos] == '+' || s[pos] == '-')) {
positive = (s[pos] == '+');
pos++;
}
auto term = parse_term(s, pos);
if (!positive) {
term.first *= -1;
term.second *= -1;
}
res.first = term.first;
res.second = term.second;
while (pos < s.size() && (s[pos] == '+' || s[pos] == '-')) {
char op = s[pos];
pos++;
auto term = parse_term(s, pos);
if (op == '+') {
res.first += term.first;
res.second += term.second;
} else {
res.first -= term.first;
res.second -= term.second;
}
}
return res;
}
int main() {
string line;
int case_num = 1;
while (getline(cin, line)) {
int eq_pos = line.find('=');
string left_str = line.substr(0, eq_pos);
string right_str = line.substr(eq_pos + 1);
int pos = 0;
auto left = parse_expression(left_str, pos);
pos = 0;
auto right = parse_expression(right_str, pos);
double total_a = left.first - right.first;
double total_b = right.second - left.second;
cout << "Equation #" << case_num << endl;
if (fabs(total_a) < EPS) {
if (fabs(total_b) < EPS) {
cout << "Infinitely many solutions." << endl;
} else {
cout << "No solution." << endl;
}
} else {
double x = total_b / total_a;
if(abs(x) <1e-9) x = abs(x);
cout << "x = " << fixed << setprecision(6) << x << endl;
}
cout << endl;
case_num++;
}
return 0;
}
E.Triangular Sums
题面

思路
加权求和,直接模拟即可
示例代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
//#define int ll
#define pii pair<int, int>
#define all(x) x.begin(),x.end()
#define fer(i, m, n) for(int i = m; i < n; ++i)
#define ferd(i, m, n) for(int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'
const int MOD = 1e9 + 7;
const int N = 2e5 + 2;
const int inf = 1e9;
signed main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
int t;
cin >> t;
fer(i, 1, t + 1) {
int n;
cin >> n;
ll ans = 0;
fer(k, 1, n + 1) ans += k * (1 + k + 1) * (k + 1) / 2;
cout << i << ' ' << n << ' ' << ans << '\n';
}
return 0;
}
F.W‘s Cipher
题面

思路
将字符串字符分成三组,将每组进行循环移位,注意处理空组串的情况
示例代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
//#define int ll
#define pii pair<int, int>
#define all(x) x.begin(),x.end()
#define fer(i, m, n) for(int i = m; i < n; ++i)
#define ferd(i, m, n) for(int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'
const int MOD = 1e9 + 7;
const int N = 2e5 + 2;
const int inf = 1e9;
void fun(string &s, int k) {
k %= s.size();
if(k < 0) k += s.size();
s = s.substr(s.size() - k) + s.substr(0, s.size() - k);
}
signed main() {
ios::sync_with_stdio(false); cin.tie(nullptr);
int k1, k2, k3;
while(cin >> k1 >> k2 >> k3, k1 || k2 || k3) {
string s;
cin >> s;
vector<int> table(s.size());
string s1, s2, s3;
fer(i, 0, s.size()) {
if(s[i] >= 'a' && s[i] <= 'i') table[i] = 1, s1 += s[i];
else if(s[i] >= 'j' && s[i] <= 'r') table[i] = 2, s2 += s[i];
else table[i] = 3, s3 += s[i];
}
if(s1.size()) fun(s1, k1);
if(s2.size()) fun(s2, k2);
if(s3.size()) fun(s3, k3);
string ans;
int ind1 = 0, ind2 = 0, ind3 = 0;
fer(i, 0, s.size()) {
if(table[i] == 1) ans += s1[ind1++];
else if(table[i] == 2) ans += s2[ind2++];
else ans += s3[ind3++];
}
cout << ans << '\n';
}
return 0;
}

浙公网安备 33010602011771号