Try   HackMD

師大附中電算社46×47第一次社內賽

題本

完整題目 PDF 檔在這裡
第一題 PDF 檔在這裡
第二題 PDF 檔在這裡
第三題 PDF 檔在這裡

題解

太陽

出題者:cyano

題敘改編自 NceS - Burn
這一題簡單來說就是分別比較

n+m
n2+m2
mn
n2+m2
是否小於等於
k
,是則輸出Yes,否則輸出No。值得注意的是C++計算
n2+m2
時可能會超過int的範圍,因此必須使用long long

#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long n, m, k;
    cin >> n >> m >> k;
    if(n + m <= k)
        cout << "Yes\n";
    else
        cout << "No\n";
    if(n * n + m * m <= k * k)
        cout << "Yes\n";
    else
        cout << "No\n";
    if(m - n <= k)
        cout << "Yes\n";
    else
        cout << "No\n";
    if(n * n + m * m <= k * k)
        cout << "Yes\n";
    else
        cout << "No\n";
}
n = int(input())
m = int(input())
k = int(input())
if n + m <= k:
    print("Yes")
else:
    print("No")
if n * n + m * m <= k * k:
    print("Yes")
else:
    print("No")
if m - n <= k:
    print("Yes")
else:
    print("No")
if n * n + m * m <= k * k:
    print("Yes")
else:
    print("No")

猜測

出題者:hi

這一題要輸出最少和最多能開出多少個寶藏,開出最少個寶藏必須要先把沒有寶藏的門全部開完再開有寶藏的,因此要計算出有多少沒有寶藏的門(

nt),如果這個數字大於能開的門的數量結果就是
0
,否則結果是能開的門的數量減掉沒有寶藏的門(
m(nt)
)。開出最多個寶藏必須要先開有寶藏的門(
t
),如果這個數字大於能開的門的數量則結果就是所有能開的門的數量(
m
),否則就是所有有寶藏的門的數量(
t
)。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long n, m, t;
    cin >> n >> m >> t;
    long long empty = n - t;
    if(empty >= m)
        cout << 0 << "\n";
    else
        cout << m - empty << "\n";
    if(t >= m)
        cout << m << "\n";
    else
        cout << t << "\n";
}
n = int(input())
m = int(input())
t = int(input())
empty = n - t
if empty >= m:
    print(0)
else:
    print(m - empty)
if t >= m:
    print(m)
else:
    print(t)

電神

出題者:R緯

這題首先要將

b 反轉,測資限制可以發現
a
必為二位數,因此
a÷10
的商就是
b
的個位數,餘就是
b
的十位數,因此b = a / 10 + a % 10 * 10(Python 為 b = a // 10 + a % 10 * 10)。接著由算幾不等式可以得知
am+bn2ambn=abk
,因為
p=am+bn
的最大值 , 因此
p=2abk
。若要知道
f(x)=ax2+bx+p,x[L,R]
的最小值是否與
f(x)=ax2+bx+p,xR
的最小值相同只需要找出
f(x)=ax2+bx+p,xR
發生時的
x=b2a
是否落在區間
[L,R]
即可,若落在區間
[L,R]
y=0
,否則
y=min(f(L),(R))

#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long a, k, L, R, b, p, y;
    double x;
    cin >> a >> k >> L >> R;
    b = a / 10 + a % 10 * 10;
    p = 2 * sqrt(a * b * k);
    x = 1.0 * -b / (2 * a);
    if(L <= x && x <= R)
        y = 0;
    else
    {
        long long y1 = a * L * L + b * L + p;
        long long y2 = a * R * R + b * R + p;
        if(y1 < y2)
            y = y1;
        else
            y = y2;
    }
    cout << p << "-" << b << "-" << y << "\n";
}
a = int(input())
k = int(input())
L = int(input())
R = int(input())
b = a // 10 + a % 10 * 10
p = 2 * int((a * b * k) ** 0.5)
x = -b / (2 * a)
y = 0
if L <= x and x <= R:
    y = 0
else:
    y1 = a * L * L + b * L + p
    y2 = a * R * R + b * R + p
    if y1 < y2:
        y = y1
    else:
        y = y2
print(p, b, y, sep = '-')

f(x)=ax2+bx+p,xR 發生時的
x=b2a
不落在區間
[L,R]
時的
y
還有另外一種解法,只需要找出
x
L
R
的距離,其中離
x
較近者就是
f(x)=ax2+bx+p,x[L,R]
最小值發生的地方。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long a, k, L, R, b, p, y;
    double x;
    cin >> a >> k >> L >> R;
    b = a / 10 + a % 10 * 10;
    p = 2 * sqrt(a * b * k);
    x = 1.0 * -b / (2 * a);
    if(L <= x && x <= R)
        y = 0;
    else
    {
        if(abs(L - x) > abs(R - x))
            y = a * R * R + b * R + p;
        else
            y = a * L * L + b * L + p;
    }
    cout << p << "-" << b << "-" << y << "\n";
}
a = int(input())
k = int(input())
L = int(input())
R = int(input())
b = a // 10 + a % 10 * 10
p = 2 * int((a * b * k) ** 0.5)
x = -b / (2 * a)
if L <= x and x <= R:
    y = 0
else:
    if abs(L - x) > abs(R - x):
        y = a * R * R + b * R + p
    else:
        y = a * L * L + b * L + p
print(p, b, y, sep = '-')

優異參賽者表揚

全場首殺

第一題:鯊鯊想睡睡(7分鐘)
第二題:1257891(13分鐘)
第三題:Zurichyoz(40分鐘)

前三名

第一名:Zurichyoz(300分)
第二名:Andrew1023666(230分)
第三名:cyan0(200分)

Fun Facts

因為 zerojudge 只能用測資獨立計分不能用子題,所以第一題直接輸出 No No No NoNo No Yes NoNo Yes Yes YesYes Yes Yes Yes 都可以得到部分分數,但好像沒有人這樣做。
還有 cyano 幫第三題加了一個

L=R1 的子題,原本以為這樣只要檢查
L
R
就好,但寫題解的時候才發現
x
是浮點數所以仍然可能會落在區間
[L,R]
,所以同樣要用滿分的解法。