COCI2015/2016 CONTEST#4 简易题解

来源:互联网 发布:基础编程书 编辑:程序博客网 时间:2024/05/19 13:17

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 longint 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 longlong 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怎么做……等官方题解吧。

0 0