牛客周赛 Round 54 题解
A 清楚姐姐的糖葫芦
思路解析:显然只需要数字符串的字符o的个数即可。
时间复杂度:
O
(
N
)
O(N)
O(N)
代码块:
void solve(){
string s;
cin>>s;
int c = 0;
for (auto v:s){
c+=v=='o';
}
cout<<c;
}
B 清楚姐姐买竹鼠
思路解析:注意问的是至少x只竹鼠的最小花费,不难发现最终只有三种情况:花费a的代价,全部一个一个买;花费b的代价,全部三个三个买,可能会超过x,但没关系;又花费a的代价,又花费b的代价,凑出恰好x只。最终三种情况取最小即可。
时间复杂度:
O
(
1
)
O(1)
O(1)
代码块:
void solve(){
ll a,b,x;
cin>>a>>b>>x;
ll res1 = x*a;
ll v = (x+2)/3 * b;
res1=min(res1,v);
res1=min(res1,x/3*b+x%3*a);
cout<<res1;
}
C 竹鼠饲养物语
思路解析:因为最多只有n次有效机会,直接从低到高模拟即可。
时间复杂度:
O
(
N
)
O(N)
O(N)
代码块:
void solve(){
int n,m;
cin>>n>>m;
vector<int> a(n);
for (int i=0;i<n;i++){
cin>>a[i];
}
sort(all(a));
map<int,int> mp;
mp[0]=1e8;
ll ans = 0;
for (auto v:a){
if (mp[v-1]){
mp[v-1]--;
mp[v]++;
ans++;
}
}
cout<<ans;
}
D 清楚姐姐跳格子
思路解析:考虑类似最短路的BFS算法,观察数据范围,发现支持O(N^2)的算法,不难想到BFS扩展的时候直接枚举长度,再考虑是否是当前权值的因子来进行扩展。
时间复杂度:
O
(
N
2
)
O(N^2)
O(N2)
代码块:
const int inf = 1e9;
void solve(){
int n;
cin>>n;
vector<ll> a(n);
for (int i=0;i<n;i++){
cin>>a[i];
}
vector<int> dis(n,inf);
dis[0]=0;
queue<int> q;
q.push(0);
while (!q.empty()){
auto v = q.front();
if (v==n-1){
break;
}
q.pop();
for (int i=1;i<=min(1ll*n,a[v]);i++){
if (a[v]%i==0){
if (v-i>=0 && dis[v]+1<dis[v-i]){
dis[v-i]=dis[v]+1;
q.push(v-i);
}
if (v+i<=n-1 && dis[v]+1<dis[v+i]){
dis[v+i]=dis[v]+1;
q.push(v+i);
}
}
}
}
cout<<dis[n-1];
}
E 清楚姐姐的布告规划
思路解析:乍一看发现类似于背包DP,如dp[i][j]表示考虑前i个物品且已经覆盖前j个位置的最少使用个数。然后这道题多了限制,那就是第i个布告要覆盖第i个位置,那很显然只需要DP转移的时候判断一下即可。
时间复杂度:
O
(
N
2
)
O(N^2)
O(N2)
代码块:
const int inf = 1e8;
void solve(){
int n;
cin>>n;
vector<int> a(n);
for (int i=0;i<n;i++){
cin>>a[i];
}
vector<int> dp(n+1,inf);
dp[0]=0;
for (int i=0;i<n;i++){
for (int j=n;j>=a[i];j--){
if (j-a[i]+1<=i+1 && j>=i+1){
dp[j]=min(dp[j],dp[j-a[i]]+1);
}
}
}
int res = dp[n];
if (res<inf) cout<<res<<'\n';
else cout<<-1<<'\n';
}