MENU

2018年全国多校算法寒假训练营练习比赛(第二场)

July 19, 2018 • Read: 3308 • 算法阅读设置

A.吐泡泡

思路

模拟题,数据小,暴力以下就行了

代码
#include <iostream>
#include <cstring>
using namespace std;
int move_One(int i,int len,char* s) {
    for(int j = i;j < len - 1;j++) 
        s[j] = s[j + 1];
    return len - 1;
}
int move_Two(int i,int len,char* s) {
    for(int j = i;j < len - 2;j++) 
        s[j] = s[j + 2];
    return len - 2;
}
int main() {
    char s[1000];
    while(scanf("%s",s) != EOF) {
        int len = strlen(s);
        for(int i = 0;i < len - 1;i++) {
            bool flag = false;
            if(s[i] == 'o' && s[i + 1] == 'o') {
                s[i] = 'O';
                len = move_One(i + 1,len,s);
                flag = true;
            }
            if(flag) {
                i = -1;
                continue;
            }
            if(s[i] == 'O' && s[i + 1] == 'O') {
                len = move_Two(i,len,s);
                flag = true;
            }
            if(flag) {
                i = -1;
                continue;
            }
        }
        for(int i = 0;i < len;i++)
            printf("%c",s[i]);
        printf("\n");    
    }
    return 0;
} 

B.TaoTao要吃鸡

思路

背包问题,只是特殊处理一下h为0和不为0的情况就行

若h=0,卡不了bug,就是正常的o-1背包

若h不等于0,可以卡bug,假设第i件武器是卡bug放进去的,那么只要01背包计算能承受总重量为m+h-1的时候的最大价值+第k件武器的价值即可

代码
import java.util.*;
public class Main {
    public static int[] w = new int[105];
    public static int[] v = new int[105];
    public static int[] dp = new int[300];
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        while(true) {
            int n,m,h;
            n = cin.nextInt();
            if(n == 0)
                break;
            m = cin.nextInt();
            h = cin.nextInt();
            for(int i = 0;i < n;i++) {
                w[i] = cin.nextInt();
                v[i] = cin.nextInt();
            }
            int ans = 0;
            for(int i = 0;i < 300;i++) 
                dp[i] = 0;
            if(h == 0) {//没有包,不能卡bug
                for(int i = 0;i < n;i++)
                    for(int j = m;j >= w[i];j--)
                        dp[j] = Math.max(dp[j],dp[j - w[i]] + v[i]);
                ans = dp[m];
            } else {//有背包,能卡bug
                for(int i = 0;i < n;i++) {
                    for(int tmp = 0;tmp < 300;tmp++) 
                        dp[tmp] = 0;
                    for(int j = 0;j < n;j++) {
                        //i不能再考虑
                        if(i == j)
                            continue;
                        for(int k = m + h - 1;k >= w[j];k--)
                            dp[k] = Math.max(dp[k],dp[k - w[j]] + v[j]);
                    }
                    ans = Math.max(ans,dp[m + h - 1] + v[i]);
                }
            }
            System.out.println(ans);
        }
    }
}

D.YB要打炉石

思路

最长非降子序列问题,由于范围比较小,直接$O(N^2)$

代码
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int n = cin.nextInt();
        if(n < 30)
            System.out.println("no");
        else {
            int ans = 0;
            int[] num = new int[105];
            int[] dp = new int[105];
            for(int i = 0;i < n;i++) {
                num[i] = cin.nextInt();
                dp[i] = 1;
            }
            for(int i = 0;i < n;i++) {
                for(int j = 0;j < i;j++) {
                    if(num[i] >= num[j])
                        dp[i] = Math.max(dp[i],dp[j] + 1);
                }
                ans = Math.max(ans,dp[i]);
            }
            if(ans >= 30)
                System.out.println("yes");
            else
                System.out.println("no");
        }
    }
}

G送分了QAQ

思路

打表枚举,首先计算出[1,1000000]满足条件的数的个数,v[i]表示[1,i]之间满足条件的数的个数,那么[L,R]之间满足条件的数的个数就是v[R] - v[L],还要判断L是否满足,L满足就加一个

代码
import java.util.*;
public class Main {
    public static int[] v = new int[1000001];
    public static boolean check(int x) {
        String s0 = "";
        String s1 = "38";
        String s2 = "4";
        s0 += x;
        if(s0.contains(s1) || s0.contains(s2))
            return true;
        return false;
    }
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        for(int i = 1;i <= 1000000;i++) {
            v[i] = v[i - 1];
            if(check(i))
                v[i]++;
        }
        while(true) {
            int n = cin.nextInt();
            int m = cin.nextInt();
            if(n == 0 && m == 0)
                break;
            else {
                long ans = v[m] - v[n];
                if(check(n))
                    ans++;
                System.out.println(ans);
            }
        }
    }
}

H.了断局

思路

规律就是a[i] = a[i - 1] + a[i - 2] + a[i - 3](i>=4)

代码
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        long[] ans = new long[60];
        ans[1] = 0;
        ans[2] = ans[3] = 1; 
        for(int i = 4;i <= 50;i++)
            ans[i] = ans[i - 1] + ans[i - 2] + ans[i - 3];
        while(cin.hasNext()) {
            int n = cin.nextInt();
            System.out.println(ans[n]);
        }
    }
}
Last Modified: May 12, 2021
Archives Tip
QR Code for this page
Tipping QR Code