北师大珠海分校2017国庆欢乐赛题解

来源:互联网 发布:php登陆注册页面模板 编辑:程序博客网 时间:2024/05/01 04:30

我都老了还让我写这种题解。

约翰·洛吉·贝尔德

每次开k个电视,需要这k个电视的色彩都不一样
每种色彩需要一根信号源
现在问至少需要多少种信号源

那么我们可以找k个电视。他们都只用1个信号源,有不同颜色,剩下的m - k个电视都需要k种信号源

python

cas = 1while True:    try:        m, k = map(int, input().split())        print("Case #" + str(cas) + ": " + str(k + (m - k) * k))        cas += 1    except:        break

c语言

#include <stdio.h>#define ll long longint main() {    ll m, k;    int cas = 1;    while (~scanf("%lld %lld", &m, &k)) {        printf("Case #%d: %lld\n", cas++, (m - k + 1) * k);    }}

拉格朗日的威严

其实是一道水题,莫名防ak

问你能不能在[L, R]里面找一个A,[X, Y]里面找一个B,使得 A / B能等于K

直接枚举X到Y,里面只要有使得i * k 在[L, R]范围里就行了。

同时枚举[X, Y] 和 [L, R]是不行的,会超时
当然也可以O(1)直接计算[B * X, B * Y] 与 [L, R]有交集

PS: python写这道题用第一种方法是过不了的,乘法时间太长了

python

T = int(input())cas = 1for tt in range(T):    l, r, x, y, k = map(int, input().split())    l += k - 1    l //= k    r //= k    flag = False if (l > r or x > r or l > y) else True    print("Case #" + str(cas) + ": " + ("YES" if flag else "NO"))    cas += 1

C语言:

#include <stdio.h>#define ll long longusing namespace std;int main() {        ll T, L, R, X, Y, K;    while (~scanf("%lld", &T)) {        int cnt = 1, flag;        while (T--) {            flag = 0;            scanf("%lld %lld %lld %lld %lld", &L, &R, &X, &Y, &K);            for(int i = X; i <= Y; i++) {                if (K * i >= L && K * i <= R) {                                     flag = 1;                    break;                }            }            if (flag) {                printf("Case #%d: YES\n",cnt++);            } else {                printf("Case #%d: NO\n",cnt++);            }        }    }    return 0;}

薛之谦的行程

题目要的是,找几段不重叠的行程,问最多多少段。

其实这道题应该是比较难一点的。
一道贪心题。
贪心取结束时间最早的,就可以拿到最多的行程了。
需要排序一下,因为总行程不多,冒泡排序也可以随意过。

python:

class xzq:    start = 0    end = 0    def __init__(self, s, e):        self.start = s        self.end = edef cmp(x):    return x.endn = int(input())num = [0] * 500ans = 0node = []for i in range(0, n):    l, r = input().split()    node.append(xzq(int(l), int(r)))node.sort(key = cmp)last = -1ans = 0for i in range(0, n):    if (last < node[i].start):        ans += 1        last = node[i].end  print(ans)

C语言:

#include <stdio.h>#include <algorithm>using namespace std;struct node {    int s, e;}k[400];bool cmp(node a, node b) {    return a.e < b.e;}int main(){    int n,last,ans;    while (scanf("%d", &n) != EOF) {        for(int i = 1; i <= n; i++){            scanf("%d %d", &k[i].s, &k[i].e);        }        sort(k + 1, k + 1 + n, cmp);        ans = 0;        last = -1;        for(int i = 1; i <= n; i++){            if (k[i].s > last) {                ans += 1;                last = k[i].e;            }        }        printf("%d\n", ans);    }    return 0;}

猫叔的绝地求生之路

题目描述已经很清楚了。
这里有几个坑点。
当k为0或者k等于n的时候,可以搜的最小房子数为0
其他最小可以搜的房子数都是1
最大可以搜的房子数是min(2 * k, n - k)

python

T = int(input())for tt in range(0, T):    a, b = map(int, input().split())    print("Case #" + str(tt + 1) + ": " + ("0 " if (a == b or b == 0) else "1 ") + str(min(2 * b, a - b)))

C语言:

#include <stdio.h>#include <algorithm>using namespace std;int main() {    int n, k, t;    while(~scanf("%d", &t)) {        int cas = 1;        while (t--) {            printf("Case #%d: ", cas++);            scanf("%d %d",&n,&k);            if(k == 0 || n == k) {                printf("0 0\n");            } else {                printf("1 %d\n", min(n - k, k * 2));            }        }    }    return 0;}

阿垃垃圾君与抽奖

一道简单的概率题,结果出题人算错了还没人质疑。。直到最后
能送出去奖品的概率等于
一次有哈士奇毛绒公仔另一次没有,一次有滑稽表情抱枕另一次没有,一次有哈士奇毛绒公仔一次有滑稽表情抱枕的概率之和。
这里要注意,由于选取有顺序的要求,要乘2答案才正确。

python:

while True:    try:        n, m, k = map(int, input().split())        ans = (n * m + n * k + m * k) / ((n + m + k) * (n + m + k))        print("%.2lf" % (ans * 2))    except:        break

C语言:

#include <stdio.h>using namespace std;int main() {    int n, m, k;    while (~scanf("%d %d %d", &n, &m, &k)) {        int t = n + m + k;        printf("%.2lf\n", 2 * (n * m + n * k + m * k) * 1.0 / (t * t));    }}

阿垃垃圾君与麋鹿

一道字符的判断题。
其实只要解决输入了,一切都好写
麋鹿可以转n次,但是只有4个方向,实际上可以看成转n % 4次
然后一个个方向判断就好了
输入的时候注意scanf(“%c %c\n%d\n”, &a, &b, &c)
python输入的没这个问题。
因为有幻影换行符

这里用hashmap对应一下个个方向的图标更好写。

python:

mapp = {'<' : 0, '^' : 1, '>': 2, 'v' : 3}while True:    try:        a, b = input().split()        c = int(input())        c %= 4        if ((mapp[a] + c) % 4 == mapp[b] and (mapp[a] - c + 4) % 4 == mapp[b]):            print("I don't know!");        elif ((mapp[a] + c) % 4 == mapp[b]):            print("clockwise");        else:            print("anti-clockwise");    except:        break

C++:

#include <stdio.h>#include <algorithm>#include <map>using namespace std;int main() {    map<char, int> mapt;    int n;    mapt['^'] = 0;    mapt['>'] = 1;    mapt['v'] = 2;    mapt['<'] = 3;    char s, e;    while (scanf("%c %c", &s, &e)) {        scanf("%d", &n);        getchar();        n %= 4;        if ((mapt[s] + n) % 4 == mapt[e] && (mapt[s] - n + 4) % 4 == mapt[e]) {            printf("I don't know!\n");        } else if ((mapt[s] + n) % 4 == mapt[e]) {            printf("clockwise\n");        } else {            printf("anti-clockwise\n");        }    }}

猫叔化身UC

其实是一道简单编码和解码的题。
但是没学过字符串的同学应该会感觉比较难
按照题意编码和解码就好了
python用数组或者hashmap再加上split的切割会更好写

python:

while True:    mapp = ["01", "1000", "1010", "100", "0", "0010", "110", "0000", "00", "0111",         "101", "0100", "11", "10", "111", "0110", "1101", "010", "000", "1", "001", "0001", "011", "1001", "1011", "1100"]    tmp = input()    l = len(mapp)    s = input()    if tmp == 'P':        l1 = len(s)        for i in range(0, l1):            if i != 0:                print('@', end='')            print(mapp[ord(s[i]) - ord('A')], end='')    else:        for ss in s.split('@'):            for i in range(0, l):                if mapp[i] == ss:                    print(chr(ord('A') + i), end='')    print()

C语言:

#include <stdio.h>#include <string.h>using namespace std;char ch[100][25] = {"01","1000","1010","100",                    "0","0010","110","0000","00","0111","101","0100",                    "11","10","111","0110","1101","010","000","1","001",                    "0001","011","1001","1011","1100"                   };int main() {    char c,mess[200];    while(scanf("%c", &c)) {        getchar();        scanf("%s", mess);        getchar();        if(c == 'P') {            int len = strlen(mess);            for(int i = 0; i < len; i++) {                printf("%s",ch[mess[i] - 65]);                if(i != len - 1)                    printf("@");            }        } else {            int len = strlen(mess), counter = 0;            char tmp[10];            for(int i = 0; i < len; i++) {                if(mess[i] == '@') {                    tmp[counter] = '\0';                    for(int j = 0; j < 26; j++) {                        if(!strcmp(ch[j],tmp))                            printf("%c",j + 65);                    }                    counter = 0;                }                 else {                    tmp[counter++] = mess[i];                }            }            tmp[counter] = '\0';            for(int j = 0; j < 26; j++) {                if(!strcmp(ch[j],tmp))                    printf("%c",j + 65);            }        }        printf("\n");    }    return 0;}

寻找小Q

其实本来这道题可以出的无限难的hhhh。
简单点让你们只有5种情况特判一下。
因为就只有5种路径可以从a走到d。

python:

i = 1while True:    try:        ab, ac, ad, bc, bd, cd = map(int, input().split())        ans = min(ab + bd, ab + bc + cd, ad, ac + cd, ac + bc + bd);        print("Case #{0}: {1}".format(i, ans))        i += 1    except:        break

C语言:

#include <stdio.h>#include <algorithm>#define ll long longusing namespace std;int main(){    int ab, ac, ad, bc, bd, cd, ans, p = 1, arr[10];    while (~scanf("%d %d %d %d %d %d",&ab, &ac, &ad, &bc, &bd, &cd)) {        arr[0] = ab + bd;        arr[1] = ab + bc + cd;        arr[2] = ad;        arr[3] = ac + cd;        arr[4] = ac + bc + bd;        ans = arr[0];        for(int i = 0; i < 5; i++) {            ans = min(ans,arr[i]);        }        printf("Case #%d: %d\n",p++, ans);    }    return 0;}

欢乐赛到此结束,希望各位能在比赛中有所收获

原创粉丝点击