啟動新賽季!
10.2
題目一覽:
題目名稱 | 躲避技能 | 奶茶兌換券 | 幫助 | 神奇的變換 |
---|---|---|---|---|
題目型別 | 傳統 | 傳統 | 傳統 | 傳統 |
檔名 | skill |
tea |
help |
change |
時空限制 | \(2s256M\) | \(1s256M\) | \(2s256M\) | \(5s256M\) |
測試點數量 | \(25\) | \(10\) | \(20\) | \(25\) |
請觀看 VCR,並回答作者表達的情感。
- \(\texttt{『S』}\) 今天我們充分發揚 PTY 告訴我們的策略!
那我們直接把暴力分拿滿!
T1
題面:有一棵樹,一些節點上有若干個箱子,要把所有箱子推到若干節點的坑中(坑中可能可以填一個或者多個),經過每一條邊都有相應代價,求完成任務最小的代價。
思路:
直接建樹爆搜,然後全排列,複雜度 \(O(m !)\)。
// Darkworldmystery 2023 ~ 2024
// #pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
using LL = long long;
const LL kMaxN = 1e5 + 5;
struct Edge
{
LL to, w;
} ;
LL n, m, s[kMaxN], imp[kMaxN], dis[15][kMaxN], id[kMaxN], ret = 1e18;
vector<Edge> nbr[kMaxN];
LL refc(string x)
{
int ret = 0;
for(int i = x.size() - 1; i >= 0; i--)
ret = ret * 10 + (x[i] - '0');
return ret;
}
void dfs(LL x, LL father, LL root = 1)
{
for(LL i = 0; i < nbr[x].size(); i++)
{
LL y = nbr[x][i].to, w = nbr[x][i].w;
if(y == father)
continue;
dis[root][y] = dis[root][x] + w;
dfs(y, x, root);
}
return ;
}
int main()
{
freopen("skill.in", "r", stdin);
freopen("skill.out", "w", stdout);
ios :: sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> m;
for(LL i = 1; i <= m; i++)
cin >> s[i], id[i] = i;
for(LL i = 1; i <= m; i++)
cin >> imp[i];
for(LL i = 1, x, y, w; i < n; i++)
{
string ww;
cin >> x >> y;
cin >> ww;
w = refc(ww);
// cerr << w << "\n";
nbr[x].push_back({y, w});
nbr[y].push_back({x, w});
}
dfs(1, 0);
for(LL i = 1; i <= m; i++)
dfs(s[i], 0, s[i]);
do
{
LL B = 0;
for(int i = 1; i <= m; i++)
B += dis[s[i]][imp[i]];
ret = min(ret, B);
} while(next_permutation(s + 1, s + 1 + m));
cout << ret << "\n";
return 0;
}
如願以償地拿到了暴力 \(\color{red} 20 pt\)。
T2
題面:玥玥有無限張價值 \(m\) 的奶茶代金券,每次玥玥會使用代金券購買兩杯奶茶。只有當代金券的總價值大於等於奶茶的總價值才可以購買,但是奶茶店是不找零的。
假設每張代金券價值 \(10\) 元,然後買了一杯 \(11\) 元和一杯 \(4\) 元的奶茶。則需要兩張代金券才能購買,但是兩張代金券價值 \(20\),奶茶總價值 \(15\),即我們可以認為玥玥這樣做浪費了 \(5\) 元。
現在已知玥玥總共購買了 \(n\) 種價值的奶茶,第 \(i\) 種奶茶購買的數量為 \(a_i\),價格為 \(b_i\)。請問玥玥最少浪費多少錢?
思路:直接列舉所有搭配,然後和這個搭配浪費的錢用 vector 存起來,然後貪浪費的錢少的,然後枚到沒了為止。
也是非常好寫。
// Darkworldmystery 2023 ~ 2024
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
using LL = long long;
const LL kMaxN = 1e5 + 5;
struct Milktea
{
LL x, price;
friend bool operator < (const Milktea &x, const Milktea &y)
{
return x.price < y.price;
}
} a[kMaxN];
struct E
{
LL a, b, D;
friend bool operator < (const E &x, const E &y)
{
return x.D < y.D;
}
} ;
vector<E> vt;
LL n, m, ret;
int main()
{
freopen("tea.in", "r", stdin);
freopen("tea.out", "w", stdout);
ios :: sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> m;
for(LL i = 1; i <= n; i++)
cin >> a[i].x >> a[i].price;
sort(a + 1, a + 1 + n);
if(n <= 1000)
{
for(LL i = 1; i <= n; i++)
for(LL j = i; j <= n; j++)
vt.push_back({i, j, (m - (a[i].price + a[j].price) % m == m ? 0 : m - (a[i].price + a[j].price) % m)});
sort(vt.begin(), vt.end());
for(auto i : vt)
{
LL x = i.a, y = i.b, w = i.D, T = min(a[x].x, a[y].x);
if(x == y)
T /= 2;
if(a[x].x <= 0 || a[y].x <= 0)
continue;
a[x].x -= T, a[y].x -= T;
ret += w * T;
}
cout << ret << "\n";
return 0;
}
cout << "1145141919810" << "\n";
return 0;
}
順利的拿到了 \(\color{orange} 30 pt\)。
另 \(30 \%\) 的性質聽了感覺非常無語,不過因為資料出鍋沒有這個性質的資料。
T3
題面:有 \(n\) 個人,第 \(i\) 個人的 EQ \(x_i\) 和 IQ \(y_i\),每個人的 EQ 都不一樣。
第 \(i\) 個人可以分享自己的 IQ 給 EQ 在 \([c_i, d_i]\) 的人,也願意接受 EQ 在 \([a_i, b_i]\) 的人,不屬於自己的 IQ 不可以再分享給別人。
在他們儘可能分享自己的腦子 IQ 的情況下,每個人的 IQ。
思路:好啊這波更簡單,直接按題意模擬。
// Darkworldmystery 2023 ~ 2024
// #pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
using LL = long long;
const LL kMaxN = 1e5 + 5;
struct Point
{
LL num, score, ans = 1, mine;
pair<LL, LL> allow, help;
} a[kMaxN];
LL n;
bool check(Point x, Point y)
{
return x.score >= y.allow.first &&
x.score <= y.allow.second &&
y.score >= x.help.first &&
y.score <= x.help.second;
}
int main()
{
freopen("help.in", "r", stdin);
freopen("help.out", "w", stdout);
ios :: sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n;
for(LL i = 1; i <= n; i++)
cin >> a[i].num, a[i].ans = a[i].num;
for(LL i = 1; i <= n; i++)
cin >> a[i].score;
for(LL i = 1; i <= n; i++)
cin >> a[i].allow.first >> a[i].allow.second >> a[i].help.first >> a[i].help.second;
if(n <= 1000)
{
for(LL i = 1; i <= n; i++)
for(LL j = i + 1; j <= n; j++)
{
if(check(a[i], a[j]))
a[j].ans += a[i].num;
if(check(a[j], a[i]))
a[i].ans += a[j].num;
}
for(LL i = 1; i <= n; i++)
cout << a[i].ans << " ";
}
return 0;
}
成功拿到了 \(\color{orange} 30 pt\)。
T4
題面:有一天,玥玥在電視上,看到了一種神奇的數字變換。
這種變換首先需要我們拿到一個正整數,然後對它分別進行以下分解:
- 分解它的質因數,數一數其質因數的指數,如果有一個質因數的指數 \(\ge 2\),寫下 \(0\);否則,若有奇數個質因數,寫下 \(−1\),否則寫下 \(1\)。
- 分解其所有正約數,寫下其約數個數以及約數總和。
顯然,對於每一個數 \(x\),經過變換後將得到 \(3\) 個整數。
玥玥試了試,發現他算出了正確的答案,他太開心了!
然而,很不幸,這一切被玥玥的老師看見了。老師總算是找到了給玥玥出題的機會,於是在第二天,老師給玥玥留了一道《好》題。
老師給玥玥了 \(n\) 個正整數,排成一排。老師讓玥玥仔細看看這個序列(名字叫 \(a\)),然後告訴了玥玥他會問 \(q\) 個問題。每一個問題中,老師給出兩個數 \(l, r\),讓玥玥算出數字 \(x\) 的答案,其中 \(x = \displaystyle\prod_{i = l} ^ {r} a_i\)
玥玥:老師,這個數(指 \(x\))太大了怎麼辦?
老師:沒關係,你只需要告訴我答案對 \(10 ^ 9 + 7\) 取模的結果就行了(完全理解成了答案太大)。實在不行的話,可以請別人幫忙哦。
這下可把玥玥難住了。她請班上 OI 最強的你來幫他解決這個問題,畢竟,這可能會給她加不少德育分啊!
老師比較善良,所以每一次回答問題時,只需要回答答案中的第 \(type\) 問就可以。注意,這裡的輸出 \(x\) 的答案指的是輸出 \(y\) 經過上述變換得到的 \(3\) 個整數中的第 \(type\) 個。
由於老師的問題是一個一個問的,所以本題強制線上。
思路:依然暴力(不過有一個 \(type = 3\) 的沒時間寫了)
// Darkworldmystery 2023 ~ 2024
// #pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
using LL = long long;
const int kMaxN = 1e5 + 5, kMod = 1e9 + 7;
int n, q, a[kMaxN], opt, T;
int main()
{
freopen("change.in", "r", stdin);
freopen("change.out", "w", stdout);
ios :: sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> q >> opt;
for(int i = 1; i <= n; i++)
cin >> a[i];
for(int l, r; q; q--)
{
cin >> l >> r;
l ^= T, r ^= T;
LL x = 1;
for(int i = l; i <= r; i++)
x *= a[i];
if(opt == 1)
{
LL sum = 0, cnt = 0;
bool f = 0;
for(int i = 2; i <= x; i++)
{
if(x % i == 0)
{
sum++;
x /= i;
}
while(x % i == 0)
f = 1, x /= i;
}
if(f == 1)
cout << "0\n", T = 0;
else if(sum & 1 == 1)
cout << kMod - 1 << "\n", T = kMod - 1;
else
cout << "1\n", T = 1;
}
else if(opt == 2)
{
LL ret = 0;
for(int i = 1; i * i <= x; i++)
{
if(x % i == 0)
{
LL j = n / i;
(ret += 2) %= kMod;
}
}
cout << (ret + kMod) % kMod << "\n";
T = (ret + kMod) % kMod;
}
// else if(opt == 3)
// {
// LL ret = 0;
// for(int i = 1; i <= sqrt(x); i++)
// {
// if(x % i == 0)
// {
// LL j = n / i;
// (ret += i + j) %= kMod;
// }
// }
// cout << (ret + kMod) % kMod << "\n";
// T = (ret + kMod) % kMod;
// }
}
return 0;
}
預估的是 \(\color{red} 24 pt\),但是折了半,只有 \(\color{red} 12 pt\),不過賽後 mmt 的一句話,讓我感覺很離譜了。
你怎麼沒有判完全平方數啊?