SDNU ACM-ICPC 2019 Training Weekly Contest 2(补题)

先简单总结一下,这次比赛的情况。这次比赛吧,是非常不理想的。

1.首先,就是审题方面,我的审题是不太行的,全队审题靠小龙,汗。。

2.接着是做题的节奏方面,做题的节奏这次也明显没有上次好,这次有点太急躁的感觉,提交的太急,审题太粗糙,也没有发挥好组队的优势。

3.其次,就是敲代码前,思路要尽量沉淀,不要脑袋一发热就敲了,占用团队时间,还影响士气,一定要尽量和队友都沟通思路,都认为可以才可以动手,简单题除外。

 

A - Alice and Bob

题目解释:俩个人约定在(x, y)点见面, 但没有指定坐标原点,且俩人一个在左下方,一个在右上方,看俩人是否碰面。

分析:水题,看约定地点x, y是否为,俩边中点。

#include
using namespace std;

int n, m, x, y;
int main()
{
    while(scanf("%d%d%d%d", &n, &m, &x, &y) != EOF)
    {
        if(2 * x  == n && 2 * y == m) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

C - Bob and math problem

题意给n个数,求组合出的最小奇数。

#include
using namespace std;
const int maxn = 120;

int n, a[maxn];
int main()
{
    while(scanf("%d", &n) != EOF)
    {
        int odd = 10, re, sum = 0;
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &a[i]);
            sum += a[i];
            if(a[i] % 2 != 0)
            {
                if(odd > a[i])
                {
                    odd = min(odd, a[i]), re = i;
                }

            }
        }
        if(odd == 10) {
            printf("-1\n");
            continue;
        }
        else if(odd == sum && n != 1)
        {
            printf("-1\n");
            continue;
        }
        else
        {
            a[re] = 15;
            sort(a, a + n);
            for(int i = n - 2; i >= 0; --i) printf("%d", a[i]);
            printf("%d\n", odd);
        }
    }
    return 0;
}

D - Boring count

D题尺取法,比较难得一题了,其实也不是特别难,就是没有想到罢了,。。。哈哈哈。

注意点:

1.尺取法但大于K个数存在时,前置点前移动。

2.一段内得子串数目,1 + 2 + 。。。+ n

#include
using namespace std;

int t, sum[50], k;
string str;
int main()
{
    scanf("%d", &t);
    while(t--)
    {
        memset(sum, 0, sizeof(sum));
        cin >> str;
        scanf("%d", &k);
        int len = str.size(), pos = 0;
        long long ans = 0;
        for(int i = 0; i < len; ++i)
        {
            sum[str[i] - 'a' + 1]++;
            while(sum[str[i] - 'a' + 1] > k)
            {
                sum[str[pos] - 'a' + 1]--;
                pos++;
            }
            ans = ans + i - pos + 1;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

F - Delete

删掉n个数使存在的不同得数目尽量多。

#include
using namespace std;
int a, b[110], c, sum, num;
int main()
{
    while(scanf("%d", &a) != EOF)
    {
        memset(b, 0, sizeof(b)); sum = 0, num = 0;
        for(int i = 0; i < a; i++)
        {
            int t;
            scanf("%d", &t); b[t]++;
        }
        for(int i = 0; i <= 100; i++)
        {
            if(b[i]) sum += (b[i] - 1), num++;
        }
        scanf("%d", &c);
        if(c <= sum) printf("%d\n", num);
        else printf("%d\n", num - (c - sum));
    }
    return 0;
}

G - Fxx and game

DP题+单调队列维护。

状态转移方程蛮简单得

dp = min(min(dp[i - l](l <= t) ) + 1, dp[i/k])+1)

优先队列维护需要注意的点

1.注意我们要的使最小的dp[i - l]

#include
using namespace std;
const int maxn = 1000100;

int T, x, k, t, dp[maxn], Q[maxn];

int main()
{
    scanf("%d", &T);
    while(T--)
    {
        memset(dp, 0x3f, sizeof(dp));
        scanf("%d%d%d", &x, &k, &t);
        if(k == 0)
        {
            if((x - 1) % t == 0)
                printf("%d\n", (x - 1) / t);
            else
                printf("%d\n", (x - 1) / t + 1);
            continue;
        }
        if(t == 0)
        {
            int ans = 0;
            while(x != 1)
            {
                x /= k;
                ans++;
            }
            printf("%d\n", ans);
            continue;
        }
        int head = 1, tail = 1;
        dp[1] = 0;
        Q[1] = 1;
        for(int i = 2; i <= x; i++)
        {
            while(head <= tail && Q[head] < i - t)
                head++;
            if(head <= tail) dp[i] = dp[Q[head]] + 1;
            if(i % k == 0) dp[i] = min(dp[i], dp[i / k] + 1); 
            while(head <= tail && dp[i] <= dp[Q[tail]]) tail--;
            Q[++tail] = i;
        }
        printf("%d\n", dp[x]);
    }
    return 0;
}

H - Fxx and string

注意点:

1.i, j, k为等比数列。

2.j | i 或 j|k 所以j只能在中间

3.枚举公比注意不要爆int

#include
#include
using namespace std;
const int maxn = 10010;

int t;
string ch;
char str[maxn];
int main()
{
    scanf("%d", &t);
    while(t--)
    {
        cin >> ch;
        int len = ch.size();
        int re = 1;
        for(int i = 0; i < len; ++i)
        {
            str[i + 1] = ch[i];
            if(str[i + 1] != 'x' && str[i + 1] != 'y' && str[i + 1] != 'r')
                str[i + 1] = ' ';
        }

        long long ans = 0;
        for(int i = 1; i < len - 1; i++)
        {
            for(int j = 1; (long long)i * j * j<= len; j++)
            {
                if(str[i] == ' ' || str[i * j] == ' ' || str[i * j * j] == ' ') continue;
                if(str[i] != str[i * j] && str[i] != str[i *j * j] && str[i * j] != str[i * j * j] && str[i * j] == 'r')
                    ans++;
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}

 

你可能感兴趣的:(SDNU ACM-ICPC 2019 Training Weekly Contest 2(补题))