2018-19賽季聯(lián)合新生訓(xùn)練賽第五場

昨天狀態(tài)不是很好,沒做出幾個題,回到宿舍很早就睡了,今早4點半突然醒了,再也睡不著了,穿上衣服,簡單洗刷之后就來到了圖書館...
打開Chrome,進(jìn)入訓(xùn)練場,看到了這個:


梁延杰

馬鴻儒

我去,原來大家都這么努力,他倆一般是12點多剛打完球,然后平時1點還在補(bǔ)題...

不說了,肝!

今早,冷靜下來,思考了當(dāng)時沒做出來的題,原來其實都那么“水”
這里提幾個相對難一些的題目的題解,其它題可以私聊我QQ
只是相對難,其實還是蠻水的(逃...

問題 B:第N個智慧數(shù)

據(jù)說這個題,咱們隊不約而同的打表,怪我...
不知道中石油張老師,看到我們工大的代碼會怎么想...可怕...

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
int n;
int num[200] = {3, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19, 20, 21, 23, 24, 25, 27, 28, 29, 31, 32, 33, 35, 36, 37, 39, 40, 41, 43, 44, 45, 47, 48, 49, 51, 52, 53, 55, 56, 57, 59, 60, 61, 63, 64, 65, 67, 68, 69, 71, 72, 73, 75, 76, 77, 79, 80, 81, 83, 84, 85, 87, 88, 89, 91, 92, 93, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 108, 109, 111, 112, 113, 115, 116, 117, 119, 120, 121, 123, 124, 125, 127, 128, 129, 131, 132, 133, 135, 136, 137};
int main()
{
    cin >> n;
    cout << num[n - 1];
    return 0;
}

問題 G:分割繩子

  • 二分例題,套用我講的二分模板就行
  • 注意,這里變換區(qū)間的時候不是Left = mid + 1;而是Left = mid + 0.001;精度問題
  • 其他地方也沒得說,注意借用此題再鞏固一下自己腦海中的二分思想
#include <iostream>
#include <algorithm>
using namespace std;
double rope[1005];
int n, m;
double ans;
double mxn;
double l, r;
bool ansok(double k)
{
    int s = 0;
    for (int i = 0; i < n; i++)
    {
        s += rope[i] / k;
    }
    if (s >= m)
        return true;
    else
        return false;
}
int main()
{
    cin >> n >> m;
    for (int i = 0; i < n; i++)
    {
        cin >> rope[i];
        mxn = max(mxn, rope[i]);
    }
    l = 0;
    r = mxn;
    while (l <= r)
    {
        double mid = (l + r) / 2;
        if (ansok(mid))
        {
            l = mid + 0.001;
            ans = mid;
        }
        else
            r = mid - 0.001;
    }
    printf("%.2f", ans);
    return 0;
}

問題 K: 單純質(zhì)因數(shù)

  • 這個題很多同學(xué)想打表,其實不用,看著數(shù)據(jù),直接算應(yīng)該沒問題,我試了試,果然沒問題
  • 把一個數(shù) num 分解質(zhì)因數(shù),同時質(zhì)因數(shù)去重累乘得到 S 看 S 是否與sum相同,如果相同就表示這是一個單純質(zhì)因數(shù)
#include <iostream>
#include <cmath>
using namespace std;
bool isp(int num)
{
    if (num == 1)
        return 0;
    if (num < 4)
        return 1;
    for (int i = 2; i <= sqrt(num); i++)
        if (num % i == 0)
            return 0;
    return 1;
}
bool isok(int num)
{
    int ok = 0;
    int s = 1;
    if (num < 6)
        return false;
    for (int i = 2; i <= sqrt(num); i++)//將此數(shù)分解質(zhì)因數(shù)
    {
        if (num % i == 0)
        {
            ok = 1;
            if (isp(i))
                s *= i;
            if ((num / i != i) && isp(num / i))
                s *= (num / i);
        }
    }
    if (s == num)//s是累乘結(jié)果
        return 1;
    else
        return 0;
}
int main()
{
    int n;
    cin >> n;
    for (int i = 6; i <= n; i++)
        if (isok(i))
            printf("%d ", i);
    return 0;
}

問題 L: 安裝飲水機(jī)

  • 這個題剛開始我想用二分...后來仔細(xì)一想大概不是,直接貪心就好,
  • 貪心思想,每次安裝飲水機(jī)都安裝在當(dāng)前觀察員能到達(dá)的遠(yuǎn)的位置(向后),如果當(dāng)前觀察員能到達(dá)上一個飲水機(jī),則這個觀察員就不必安裝飲水機(jī),繼續(xù)往后枚舉
  • 但這里有個問題,當(dāng)一個觀察員的覆蓋范圍在另一個觀察員覆蓋范圍之內(nèi)就會出問題
  • 這時我想到要去重,把范圍大的觀察員全部踢掉,因為如果我們能滿足一個小范圍的觀察員的飲水需求,那么能到達(dá)這個小范圍觀察員的其它所有大范圍觀察員都能被滿足。想一想


    image.png
  • 這里每個顏色各表示一個觀察員的覆蓋范圍,如果我們能滿足綠色觀察員的飲水需求,也就是我們在綠色范圍內(nèi)建一個飲水機(jī)的話,紅色和黑色我們還需要考慮嘛?
    當(dāng)然不用,因為他們兩個一定能到達(dá)綠色那里,當(dāng)然藍(lán)色就不一定了。
  • 這個時候我們把飲水機(jī)盡量建在綠色最右邊,繼續(xù)枚舉下一個觀察員,如果下一個觀察員的范圍能與綠色相交,我們自然也不用考慮啊,如果不相交,那就在他的最右邊安裝飲水機(jī)就好了
  • 關(guān)鍵步驟:排序,去重
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
int n;
int v[2000];
struct ss
{
    int k;
    int l;
    int r;
} s[1005];
bool cmp(ss a, ss b)
{
    if (a.r == b.r)
        return a.l < b.l;
    else
        return a.r < b.r;
}
int main()
{
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        int p;
        cin >> s[i].k >> p; //k表示觀察員的坐標(biāo),l是左邊界,r是右邊界
        s[i].l = s[i].k - p;
        s[i].r = s[i].k + p;
    }
    sort(s, s + n, cmp); //安裝我的規(guī)則排序,先安裝右邊界,再安裝左邊界
    for (int i = 0; i < n; i++)
    {
        for (int j = i + 1; j < n; j++)
        {
            if (s[j].l > s[i].l)
                break;
            if (s[j].r < s[i].r)
                continue;
            if (s[j].r >= s[i].r && s[j].l <= s[i].l)
                v[j] = 1; //去重我們就標(biāo)記一下就好了,到時候直接跳過就行
        }
    }
    int now = s[0].r;
    int ans = 1;
    for (int i = 1; i < n; i++)
    {
        if (v[i])
            continue;
        if (s[i].l <= now) //如果當(dāng)前觀察員能到達(dá)上一個飲水機(jī),那就不用安裝新的飲水機(jī)
            continue;
        if (s[i].l > now) //如果當(dāng)前觀察員不能到達(dá),那就安裝飲水機(jī)
        {
            ans++;
            now = s[i].r;
        }
    }
    cout << ans;
    return 0;
}
  • 這個題數(shù)據(jù)真的水,不跳過大區(qū)間都能過...
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容