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

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

约翰·洛吉·贝尔德

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

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

python

cas = 1
while 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 long

int 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 = 1
for 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 long

using 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 = e

def cmp(x):
    return x.end

n = int(input())
num = [0] * 500
ans = 0
node = []
for i in range(0, n):
    l, r = input().split()
    node.append(xzq(int(l), int(r)))

node.sort(key = cmp)

last = -1
ans = 0

for 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 = 1
while 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 long

using 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;
}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值