WaterAngel题解Codeforces Round #799 (Div. 4)

A : 直接输出数值比A大的完事

void solve() {
    int a, x, ans = 0;
    cin >> a;
    for (int i = 1; i <= 3; i++) {
        cin >> x;
        if (x > a) {
            ans++;
        }
    }
    cout << ans << endl;
    return;
}

B :len表示的是有多少种数字,(n-len)% 2 模拟了每个数字各留一个的情况下剩什么数字,如果发现消完还是有数字是只有一个的,那么这个数字只能被抛弃了。

void solve() {
    int n, x = -1, len = 0, ans = 0;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    sort(a + 1, a + 1 + n, cmd);
    for (int i = 0; i <= n; i++) {
        m[i] = 0;
    }
    a[0] = -1;
    for (int i = 1; i <= n; i++) {
        if (a[i] > a[i - 1]) {
            len++;
        }
    }
    if (len == n) {
        ans = n;
        cout << n << endl;
        return;
    }
    if ((n - len) % 2 == 1) {
        ans = len - 1;
    } else if ((n - len) % 2 == 0) {
        ans = len;
    }
    cout << ans << endl;
    return;
}

C :纯模拟,感觉对我来说比B简单

//OIer要相信模法

int dx[5] = {-1, -1, 0, 1, 1};
int dy[5] = {-1, 1, 0, -1, 1};
void solve() {
    char s[10][10];
    for (int i = 1; i <= 8; i++) {
        for (int j = 1; j <= 8; j++) {
            cin >> s[i][j];
        }
    }
    for (int i = 2; i <= 7; i++) {
        for (int j = 2; j <= 7; j++) {
            bool ff = true;
            for (int k = 0; k < 5; k++) {
                if (s[i + dx[k]][j + dy[k]] != '#') {
                    ff = false;
                    break;
                }
            }
            if (ff) {
                printf("%d %d\n", i, j);
                return;
            }
        }
    }
    return;
}

D : 找回文时钟,只要模拟他看表的动作就行,然后判断是不是已经看完一轮了 

string s[16] = {"00:00", "01:10", "02:20", "03:30", "04:40", "05:50",
                "10:01", "11:11", "12:21", "13:31", "14:41", "15:51",
                "20:02", "21:12", "22:22", "23:32"};
void solve() {
    string tt;
    int x, ans = 0;
    cin >> tt >> x;
    int minm = ((tt[4]) - '0') + ((tt[3]) - '0') * 10;
    int hour = ((tt[1]) - '0') + ((tt[0]) - '0') * 10;
    if (tt[0] == tt[4] && tt[2] == tt[3])
        ans++;

    int mp = x % 60, hp = x / 60;
    int hc = hour + hp + (minm + mp) / 60;
    hc %= 24;
    int mc = (minm + mp) % 60;
    if (hc / 10 == mc % 10 && hc % 10 == mc / 10)
        ans++;
    while (hc != hour || mc != minm) {
        hc = hc + hp + (mc + mp) / 60;
        hc %= 24;
        mc = (mc + mp) % 60;
        if (hc / 10 == mc % 10 && hc % 10 == mc / 10)
            ans++;
        // cout << hc / 10 << hc % 10 << ":" << mc / 10 << mc % 10 << endl;
    }
    cout << ans << endl;
    return;
}

E : 如果是OI自己暴力吧,可惜不是。那么想想优化感觉只能做二分查找了,

先记录到这个数字为止的数组,加和为几,然后从后往前遍历,找到超出不需要的部分,再计算删除两端需要的代价

//英语渣渣,英文凑合看吧

pos 就是二分查找过程,注意因为有可能重复所以往前看看,两端越远代价越小。

int pos(int k, int fn) {
    int l = 1, r = fn;
    while (l < r) {
        int mid = (l + r) / 2;
        if (a[mid] == k) {
            int nmn = mid;
            while (a[nmn] == k) {
                nmn--;
                if (a[nmn] != k) {
                    return nmn + 1;
                }
            }
            // return mid;
        }
        if (a[mid] > k) {
            r = mid;
        } else if (a[mid] < k) {
            l = mid;
        }
    }
}
void solve() {
    int n, s;
    cin >> n >> s;
    int ans = n, cnt = 0;
    a[0] = 0;
    b[n + 1] = 0;
    for (int i = 1; i <= n; i++) {
        cin >> x[i];
        a[i] = a[i - 1] + x[i];
        if (x[i] == 1) {
            cnt++;
        }
    }
    if (jdg_quit(cnt, s)) {
        return;
    }
    // del the number from left cost value "i"
    // del the number from right cost value "n-j+1"

    for (int i = n; i >= 1; i--) {
        if (a[i] < s)
            break;
        if (a[i] == s) {
            ans = min(ans, n - i);
        }
        if (a[i] > s) {
            ans = min(ans, n - i + pos(a[i] - s, i));
        }
    }

    cout << ans << endl;
}

F :直接暴力,既然需要最后一位那我们只看最后一位,判断数字够不够用就行

int cmd(int aa, int bb) {
    return aa < bb;
}
void solve() {
    int n, x;
    cin >> n;
    for (int i = 0; i <= 9; i++) {
        f[i] = 0;
    }
    for (int i = 1; i <= n; i++) {
        cin >> x;
        x %= 10;
        f[x]++;
    }

    for (int i = 0; i <= 9; i++) {
        for (int j = i; j <= 9; j++) {
            for (int k = j; k <= 9; k++) {
                if ((i + j + k) % 10 == 3) {
                    if (f[i] == 0 || f[j] == 0 || f[k] == 0) {
                        continue;
                    }
                    if (i == j && f[i] < 2) {
                        continue;
                    }
                    if (i == k && f[i] < 2) {
                        continue;
                    }
                    if (j == k && f[j] < 2) {
                        continue;
                    }
                    if (i == j && j == k && i == k && f[i] < 3) {
                        continue;
                    }
                    cout << "YES" << endl;
                    return;
                }
            }
        }
    }
    cout << "NO" << endl;
}

G : 记录下 2 * a[i] > a[i-1] 的长度,用 f[i] 保存,长度 >= k + 1 就是合法的。ans++

void solve() {
    int n, k, ans = 0;
    cin >> n >> k;
    a[0] = 0;
    f[0] = 0;
    for (int i = 1; i <= n; i++) {
        f[i] = 1;
        cin >> a[i];
        if (2 * a[i] > a[i - 1]) {
            f[i] = f[i] + f[i - 1];
        }
        if (f[i] >= k + 1) {
            ans++;
        }
    }
    cout << ans << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值