A 不想走

  • 求一下最短的距离就好了
    1
    2
    3
    4
    5
    6
    7
    8
    signed main() {
    IOS;
    int a, b, x, y;
    cin >> a >> b >> x >> y;
    cout << min({abs(b - a), abs(a - x) + abs(y - b), abs(a - y) + abs(b - x)}) << endl;

    return 0;
    }

B 连续数求和

  • 直接暴力就好了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    int main() {
    int T;
    cin>>T;
    for(int i=1;i<=100000;i++)
    {
    a[i]=a[i-1]+i;
    }
    for(int i=1;i<=T;i++)
    {
    cin>>n;
    for(int j=2;j<=100000;j++)
    {
    if(n<a[j])
    {
    cout<<"IMPOSSIBLE\n";
    break;
    }
    else
    {
    if(n%j==a[j]%j)
    {
    int tmp=n/j-a[j]/j;
    cout<<n<<" = ";
    for(int k=1;k<j;k++)
    {
    cout<<k+tmp<<" + ";
    }
    cout<<j+tmp<<"\n";
    break;
    }
    }
    }
    }
    return 0;
    }

C 琴魔

  • 用链表求一下所有的联通快就好了,注意是只有一个环还是多出来一块,要分类讨论一下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    #define MAX 110
    int a[MAX], in[MAX], e[MAX], st[MAX];
    int n;

    signed main() {
    IOS;
    cin >> n;
    for (int i = 1; i <= n; i++) {
    cin >> a[i];
    }
    sort(a + 1, a + 1 + n);
    e[1] = 2, e[n] = n - 1, in[2]++, in[n - 1]++;
    for (int i = 2; i < n; i++) {
    if (a[i] - a[i - 1] <= a[i + 1] - a[i]) {
    e[i] = i - 1, in[i - 1]++;
    } else {
    e[i] = i + 1, in[i + 1]++;
    }
    }
    ll res = 0;
    for (int i = 1; i <= n; i++) {
    if (!st[i] && !in[i]) {
    int E = i;
    while (E) {
    if (st[E]) break;
    st[E] = 1;
    E = e[E];
    }
    res++;
    }
    }
    for (int i = 1; i <= n; i++) {
    if (!st[i]) {
    int E = i;
    while (E) {
    if (st[E]) break;
    st[E] = 1;
    E = e[E];
    }
    res++;
    }
    }
    cout << res << endl;
    return 0;
    }

D. 素数分解

  • 写个筛法跑一遍背包就好了
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #define MAX 20005
    int st[MAX], p[MAX], cnt;
    int DP[MAX];
    int n;
    void Eratosthenes(){
    for(int i=2; i<=n;i++){
    if(!st[i]){
    p[++cnt]=i;
    }
    for(int j=1;j<=cnt&&i*p[j]<=n;j++){
    st[i*p[j]]=1;
    if(i%p[j]==0){
    break;
    }
    }
    }
    }

    signed main() {
    IOS;
    cin >> n;
    Eratosthenes();
    fill(DP, DP + n + 1, -1e9);
    DP[0] = 0;
    for (int i = 1; i <= cnt; i++) {
    int a = p[i];
    //cout << a << endl;
    for (int j = n; j >= a; j--) {
    DP[j] = max(DP[j], DP[j - a] + 1);
    //cout << DP[j] << ' ';
    }
    //cout << endl;
    }
    cout << DP[n] << endl;
    return 0;
    }

E 勇者斗恶龙

  • 重点是要先枚举位置再枚举装备,再更新完装备后再看看能扔几件装备
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #define MAX 20005
    int st[MAX], p[MAX], cnt;
    int DP[MAX];
    int n;
    void Eratosthenes(){
    for(int i=2; i<=n;i++){
    if(!st[i]){
    p[++cnt]=i;
    }
    for(int j=1;j<=cnt&&i*p[j]<=n;j++){
    st[i*p[j]]=1;
    if(i%p[j]==0){
    break;
    }
    }
    }
    }

    signed main() {
    IOS;
    cin >> n;
    Eratosthenes();
    fill(DP, DP + n + 1, -1e9);
    DP[0] = 0;
    for (int i = 1; i <= cnt; i++) {
    int a = p[i];
    //cout << a << endl;
    for (int j = n; j >= a; j--) {
    DP[j] = max(DP[j], DP[j - a] + 1);
    //cout << DP[j] << ' ';
    }
    //cout << endl;
    }
    cout << DP[n] << endl;
    return 0;
    }

F 公平正义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
const int N = 20, V =3005;
int DP[N][V][2];
int num[N];
int NP;

int dfs(int n, int now, int lim) {
if (now < 0) {
return 0;
}
if(n == 0) return now == 0;
if (~DP[n][now][lim]) return DP[n][now][lim];
int res = 0,UP = lim ? num[n] : 9;
for (int i = 0; i <= UP; i++) {
res += dfs(n - 1, now + (n - NP) * i, lim && i == UP);
}
return DP[n][now][lim] = res;
}

int solve(int n) {
int cnt = 0;
while (n) {
num[++cnt] = n % 10;
n /= 10;
}
int res = 0;
for (int i = 1; i <= cnt; i++) {
memset(DP, -1, sizeof(DP));
NP = i;
res += dfs(cnt, 0, 1);
}
return res - cnt + 1;
}

signed main() {
IOS;
int L, R;
cin >> L >> R;
cout << solve(R) - solve(L - 1) << endl;
return 0;
}