T1:幸运儿

幸运儿是 (x1+m1)%n+1

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n, x, m;
cin >> n >> x >> m;
--x;
int ans = (x+m-1)%n+1;
cout << ans << '\n';
return 0;
}

T2:下降幂多项式

模拟

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
//const int mod = 998244353;
const int mod = 1000000007;
struct mint {
ll x;
mint(ll x=0):x((x%mod+mod)%mod) {}
mint operator-() const {
return mint(-x);
}
mint& operator+=(const mint a) {
if ((x += a.x) >= mod) x -= mod;
return *this;
}
mint& operator-=(const mint a) {
if ((x += mod-a.x) >= mod) x -= mod;
return *this;
}
mint& operator*=(const mint a) {
(x *= a.x) %= mod;
return *this;
}
mint operator+(const mint a) const {
return mint(*this) += a;
}
mint operator-(const mint a) const {
return mint(*this) -= a;
}
mint operator*(const mint a) const {
return mint(*this) *= a;
}
mint pow(ll t) const {
if (!t) return 1;
mint a = pow(t>>1);
a *= a;
if (t&1) a *= *this;
return a;
}
// for prime mod
mint inv() const {
return pow(mod-2);
}
mint& operator/=(const mint a) {
return *this *= a.inv();
}
mint operator/(const mint a) const {
return mint(*this) /= a;
}
};
istream& operator>>(istream& is, mint& a) {
return is >> a.x;
}
ostream& operator<<(ostream& os, const mint& a) {
return os << a.x;
}
int main() {
int n, m;
cin >> n >> m;
vector<int> a(n+1);
rep(i, n+1) cin >> a[i];
reverse(a.begin(), a.end());
mint ans, coef = 1;
rep(i, n+1) {
ans += coef*a[i];
coef *= m-i;
}
cout << ans << '\n';
return 0;
}

T3:假期

简单dp

dp[i][j] 表示第 i 天选择了活动 j 使得前 i 天得到分数总和的最大值

原题:Vacation

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
inline void chmax(int& x, int y) { if (x < y) x = y; }
int main() {
int n;
cin >> n;
vector dp(n+1, vector<int>(3));
rep(i, n) {
vector<int> a(3);
rep(j, 3) cin >> a[j];
rep(j, 3)rep(k, 3) if (j != k) {
chmax(dp[i+1][j], dp[i][k]+a[j]);
}
}
int ans = 0;
rep(i, 3) chmax(ans, dp[n][i]);
cout << ans << '\n';
return 0;
}

T4:素数行列

  • 先筛出 2e5 以内所有的素数
  • 然后求出每个数变成大于或等于它的第一个素数的代价
  • 最后遍历每行每列里所有数的代价总和取最小值即可

原题:CF271B

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
// linear sieve
vector<bool> isp;
vector<int> ps, pf;
void sieve(int mx) {
isp.resize(mx+1);
pf.resize(mx+1);
rep(i, mx+1) pf[i] = i;
for (int i = 2; i <= mx; ++i) {
if (pf[i] == i) isp[i] = true, ps.push_back(i);
rep(j, ps.size()) {
int x = ps[j] * i;
if (x > mx) break;
pf[x] = ps[j];
}
}
}
int main() {
sieve(2e5);
int n;
cin >> n;
vector c(n, vector<int>(n));
rep(i, n)rep(j, n) {
int x;
cin >> x;
while (!isp[x]) {
x++;
c[i][j]++;
}
}
int ans = 1001001001;
rep(i, n) {
int s = 0;
rep(j, n) s += c[i][j];
ans = min(ans, s);
}
rep(j, n) {
int s = 0;
rep(i, n) s += c[i][j];
ans = min(ans, s);
}
cout << ans << '\n';
return 0;
}

T5:方格路径

注意到这题可以向上或向左走,不满足无后效性,所以不能 dp

我们可以用 bfs + 简单递推解决

在我们求到当前点的最短路时,可以同时更新到当前点的最短路的路径数

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;
//const int mod = 998244353;
const int mod = 1000000007;
struct mint {
ll x;
mint(ll x=0):x((x%mod+mod)%mod) {}
mint operator-() const {
return mint(-x);
}
mint& operator+=(const mint a) {
if ((x += a.x) >= mod) x -= mod;
return *this;
}
mint& operator-=(const mint a) {
if ((x += mod-a.x) >= mod) x -= mod;
return *this;
}
mint& operator*=(const mint a) {
(x *= a.x) %= mod;
return *this;
}
mint operator+(const mint a) const {
return mint(*this) += a;
}
mint operator-(const mint a) const {
return mint(*this) -= a;
}
mint operator*(const mint a) const {
return mint(*this) *= a;
}
mint pow(ll t) const {
if (!t) return 1;
mint a = pow(t>>1);
a *= a;
if (t&1) a *= *this;
return a;
}
// for prime mod
mint inv() const {
return pow(mod-2);
}
mint& operator/=(const mint a) {
return *this *= a.inv();
}
mint operator/(const mint a) const {
return mint(*this) /= a;
}
};
istream& operator>>(istream& is, mint& a) {
return is >> a.x;
}
ostream& operator<<(ostream& os, const mint& a) {
return os << a.x;
}
const int di[] = {0, 1, 0, -1};
const int dj[] = {1, 0, -1, 0};
int main() {
int n, m;
cin >> n >> m;
vector<string> s(n);
rep(i, n) cin >> s[i];
const int INF = 1001001001;
vector dist(n, vector<int>(m, INF));
vector dp(n, vector<mint>(m));
queue<P> q;
dist[0][0] = 1;
dp[0][0] = 1;
q.emplace(0, 0);
while (q.size()) {
auto [i, j] = q.front(); q.pop();
rep(v, 4) {
int ni = i+di[v], nj = j+dj[v];
if (ni < 0 or ni >= n or nj < 0 or nj >= m or s[ni][nj] == '#') continue;
if (dist[ni][nj] == INF) {
dist[ni][nj] = dist[i][j]+1;
q.emplace(ni, nj);
}
if (dist[ni][nj] == dist[i][j]+1) {
dp[ni][nj] += dp[i][j];
}
}
}
cout << dp[n-1][m-1] << '\n';
return 0;
}