COCI2015/2016 CONTEST#4 简易题解

T1:YODA
题意:给出两个数,要求把两个数对撞,每一个十进制位上的大的留在原数,如果相同,两个都留在原数,最后输出两个对撞后的原数。
思路:直接模拟即可,两个数每一次都/10%10,比较是否合法。

#include<cstdio>
#include<cstring>
char s1[20], s2[20];
int main() {
    scanf("%s%s", s1, s2);
    int N = strlen(s1), M = strlen(s2);
    for(int i = N-1, j = M-1; i >= 0 && j >= 0; -- i, -- j) {
        if(s1[i] > s2[j]) s2[j] = 0;
        else if(s1[i] < s2[j]) s1[i] = 0;
    }
    int n = -1, m = -1;
    for(int i = 0; i < N; ++ i)
        if(s1[i]) {
            if(n == -1) n = 0;
            n = n * 10 + s1[i] - '0';
        }
    for(int i = 0; i < M; ++ i)
        if(s2[i]) {
            if(m == -1) m = 0;
            m = m * 10 + s2[i] - '0';
        }
    if(n == -1) puts("YODA");
    else printf("%d\n", n);
    if(m == -1) puts("YODA");
    else printf("%d\n", m);
    return 0;
}

T2:HAN
题意:恶心模拟
思路:步数%26并作出相应操作。

#include<cstdio>
#include<algorithm>
using namespace std;
#define LL long long
int n, f, cur, st;
int cnt[30];
char c;
inline void GET(int &n) {
    do c = getchar(); while('0' > c || c > '9'); n = 0;
    while('0' <= c && c <= '9') {n = n*10+c-'0'; c = getchar();}
}
int main () {
    int t1, t2; f = 1; cur = 0;
    char op[10];
    GET(n);
    for(int i = 1; i <= n; ++ i) {
        scanf("%s", op);
        if(op[0] == 'S') {
            GET(t1);
            if(t1 - st >= 26) while(cur) { cur = ((cur + f) % 26 + 26) % 26, ++ st; ++ cnt[cur];}
            for(int i = 0; i < 26; ++ i) cnt[i] += (t1 - st) / 26;
            st += (t1 - st)/26*26;
            for(; st < t1; ++ st) {
                cur = ((cur + f) % 26 + 26) % 26;
                ++ cnt[cur];
            }
            f *= -1; st = t1;
        }
        else {
            GET(t1); scanf("%s", op); t2 = (op[0] - 'a' + 1)%26;
            if(t1 - st >= 26) while(cur) { cur = ((cur + f) % 26 + 26) % 26, ++ st; ++ cnt[cur];}
            for(int i = 0; i < 26; ++ i) cnt[i] += (t1 - st) / 26; st += (t1 - st)/26*26;
            for(; st < t1; ++ st) {
                cur = ((cur + f) % 26 + 26) % 26;
                ++ cnt[cur];
            }
            st = t1;
            printf("%d\n", cnt[t2]);
        }
    }
    return 0;
}

T3:DEATHSTAR
题意:给你一个矩阵 第(i,j)表示Ai&Aj (&表示按位与(bitwise and))求数列{An}
思路:想想或运算,你知道了吗?

#include<cstdio>
int a[1005][1005], n;
int arr[1005];
char c;
inline void GET(int &n) {
    do c = getchar(); while('0' > c || c > '9'); n = 0;
    while('0' <= c && c <= '9') {n = n*10+c-'0'; c = getchar();}
}
int main () {
    GET(n);
    for(int i = 1; i <= n; ++ i)
        for(int j = 1; j <= n; ++ j) {
            GET(a[i][j]);
            arr[i] |= a[i][j];
            arr[j] |= a[i][j];
        }
    printf("%d", arr[1]);
    for(int i = 2; i <= n; ++ i)
        printf(" %d", arr[i]);
    return 0;
}

T4:HEWBACCA
题意:给你一个完全K叉树,求两点间的距离。
思路:因为是完全K叉数,那么暴力爬树就是完全没有问题的了(1叉树需要特判)。

#include<cstdio>
#include<algorithm>
using namespace std;
#define LL long long
long long p[100], n, m, k, q;
char c;
inline void GET(LL &n) {
    do c = getchar(); while('0' > c || c > '9'); n = 0;
    while('0' <= c && c <= '9') {n = n*10+c-'0'; c = getchar();}
}
LL fa(LL x) {
    int t = lower_bound(p+1, p+q+1, x) - p;
    LL o = x - p[t-1];
    o = (o+k-1)/k;
    return p[t-2]+o;
}
int dep(LL x) {
    return lower_bound(p, p+q+1, x) - p;   //其实这里可以直接写 "return x;"。因为编号适合深度有关的……我当时SB了
}
int main () {
    GET(n); GET(k); GET(m);
    p[2] = 1; LL t1, t2;
    if(k != 1) {
        for(q = 3; n / p[q-1] > k; ++ q) p[q] = p[q-1] * k;
        for(int i = 1; i <= q; ++ i) p[i] += p[i-1];
        p[q] = n;
    }
    for(int i = 1; i <= m; ++ i) {
        int tot = 0;
        GET(t1); GET(t2);
        if(t1 > t2) swap(t1, t2);
        if(k == 1) printf("%I64d\n", t2 - t1);
        else {
            while(t1 != t2) {
                if(dep(t1) < dep(t2)) swap(t1, t2);
                t1 = fa(t1); ++ tot;
            }
            printf("%d\n", tot);
        }
    }
    return 0;
}

暂时到这里了,我并不知道T5、T6怎么做……等官方题解吧。

转载于:https://www.cnblogs.com/geng4512/p/5296881.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值