这道题目没开出来,这把实在打的太唐了。
总结而言,有三点问题:
第一是这个没看榜,还是要经常看榜,观察这个题目的出题速度,人数变化情况,一旦这个人数超过 5000 以上,或者在比赛未过半的时候达到 3000,那么就说明这道题目就是非常简单 ,还是能比较简单的可以看出来/猜出来的 (就比如说这道题目,这个神秘小性质还是很简单的)。
其实也没有其他问题,div3 的经验我确实比较少,最近打的比较少。
题目大意
给定一个包含 N 个苹果的堆,每次可以将一个堆分成两个堆,如果原堆有 x 个苹果,则分成 ⌊x/2⌋ 和 ⌈x/2⌉ 两个堆,每次分堆需要 1 分钟。
问能否通过若干次分堆操作得到一个恰好包含 K 个苹果的堆?如果可以,求最少需要多少分钟。
输入:
输出:
对于每个测试用例,如果无法得到恰好 K 个苹果的堆,输出 -1;否则输出最少需要的分钟数。
思路讲解
其实这道题目只需要一个关键结论,就是第 k k k 步只可能产生 ⌊ N 2 k ⌋ \lfloor\frac{N}{2^k}\rfloor ⌊ 2 k N ⌋ 或者 ⌈ N 2 k ⌉ \lceil\frac{N}{2^k}\rceil ⌈ 2 k N ⌉ (当然这两个可能相等)。因此就猜一下就可以了。
当然,利用这个结论,也可以写一个记忆化 bfs,详细地来说,用一个 set 存一下,搜过的数字就不继续搜了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 while (!q.empty ()) { auto [x,step]=q.front (); q.pop (); if (x==K) { cout<<step<<"\n" ; return ; } if (x<K) { continue ; } auto res=st.emplace (x/2 ,step+1 ); bool con=!res.second; if (!con) { q.emplace (x/2 ,step+1 ); } res=st.emplace ((x+1 )/2 ,step+1 ); con=!res.second; if (!con){ q.emplace ((x+1 )/2 ,step+1 ); } } cout<<-1 <<"\n" ;
AC代码
AC
https://codeforces.com/contest/2184/submission/357642090
源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 #include <bits/stdc++.h> #include <ranges> #define all(vec) vec.begin(),vec.end() #define lson(o) (o<<1) #define rson(o) (o<<1|1) #define SZ(a) ((long long) a.size()) #define debug(var) cerr << #var <<":" <<var<<"\n" ; #define cend cerr<<"\n-----------\n" #define fsp(x) fixed<<setprecision(x) using namespace std;using ll = long long ;using ull = unsigned long long ;using DB = double ;using LD = long double ;using CD = complex<double >;static constexpr ll MAXN = (ll)1e6 +10 , INF = (1ll <<61 )-1 ;static constexpr ll mod = 998244353 ; static constexpr double eps = 1e-8 ;const double pi = acos (-1.0 );ll lT; struct x_step { ll x,step; bool operator <(const x_step & o) const { if (x!=o.x) return x<o.x; return step<o.step; } x_step (ll x,ll step):x (x),step (step) { } }; void Solve () { ll N,K; cin >> N >> K; queue<x_step> q; q.push ({N,0 }); set<x_step> st; while (!q.empty ()) { auto [x,step]=q.front (); q.pop (); if (x==K) { cout<<step<<"\n" ; return ; } if (x<K) { continue ; } auto res=st.emplace (x/2 ,step+1 ); bool con=!res.second; if (!con) { q.emplace (x/2 ,step+1 ); } res=st.emplace ((x+1 )/2 ,step+1 ); con=!res.second; if (!con){ q.emplace ((x+1 )/2 ,step+1 ); } } cout<<-1 <<"\n" ; } signed main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); cout.tie (nullptr ); cin >> lT; while (lT--) Solve (); return 0 ; }
心路历程(WA,TLE,MLE……)