前言:
如今已经回到返校回家,在家中的学习热情明显下降,在加上练车、和朋友亲戚聚一聚,学习的时间明显下降,希望自己能更加努力一点吧,之后想通过发博客来监督自己在暑假家中的努力,希望自己能做到每日发表至少一篇博客来记录自己的学习进程吧!
正文:
链接:(1条未读私信) 牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com)
A 清楚姐姐的糖葫芦:
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
int ans=0;
cin>>s;
for(int i=0;i<s.size();i++){
if(s[i]=='o')ans++;
}
cout<<ans<<endl;
return 0;
}
签到题,没什么好说的。
B 清楚姐姐买竹鼠:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
ll a,b,x;
ll ans=1;
cin>>a>>b>>x;
if(a*3<=b){
ans=(ll)a*x;
}
else{
ans*=(x/3)*b;
ll cnt=x%3;
ans+=min(cnt*a,b);
}
cout<<ans<<endl;
return 0;
}
分情况来讨论是一个一个买还是一起买。
C 竹鼠饲养物语:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100005];
ll b[100005];
int main(){
int n,m;
ll ans=0;
cin>>n>>m;
b[1]=1000000000;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+n+1);
int level=1;
for(int i=1;i<=n;i++){
//cout<<i<<" "<<level<<" "<<b[level]<<endl;
if(level+1<a[i])break;
if(a[i]==level&&b[level]!=0){
b[level]--;b[level+1]++;ans++;
}
else if(a[i]!=level){
level++;
i--;
}
}
cout<<ans<<endl;
return 0;
}
直接遍历看当前这个竹鼠是否能升级,能就更新答案并让升级后的竹鼠加一,不能就往后遍历,如果已经出现断层(无法在升级)就直接结束遍历。
D 清楚姐姐跳格子:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<ll> a[1005];
ll b[1005];
bool book[1005];
int n;
int bfs(int x,int cnt){
queue<pair<int,int> > q;
q.push({x,cnt});
while(!q.empty()){
pair<int,int> k=q.front();
//cout<<k.first<<endl;
if(k.first==n){
return k.second;
}
q.pop();
b[k.first]=true;
for(vector<ll>::iterator it=a[k.first].begin();it!=a[k.first].end();it++){
ll l=*it+k.first,r=k.first-*it;
//cout<<l<<r<<endl;
if(l>=1&&l<=n){
if(!book[l]){
q.push({l,k.second+1});
book[l]=true;
}
}
if(r>=1&&r<=n){
if(!book[r]){
q.push({r,k.second+1});
book[r]=true;
}
}
}
}
return -1;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
scanf("%lld",&b[i]);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=b[i]/j;j++){
if(j>=1000)break;
ll res=b[i]/j;
if(b[i]%j==0){
if(j<1000)a[i].push_back(j);
if(j!=res&&res<1000)a[i].push_back(res);
}
}
}
//for(int i=1;i<=n;i++){
// for(vector<ll>::iterator it=a[i].begin();it!=a[i].end();it++){
// cout<<*it<<" ";
// }
// cout<<endl;
// }
cout<<bfs(1,0);
return 0;
}
bfs搜索加减枝,现预处理所有点的约数,并将大于等于1000的约数都给舍去(不能出界),然后从第一个开点始搜索所有没搜索过的合法点,直至搜索到最后一个点,记录下来的层数即为答案。
E 清楚姐姐的布告规划:
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long
const int N = 1000 + 10;
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
int a[maxn];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T;
cin >> T;
while (T--){
int n;
cin >> n;
for (int i = 1; i <= n; i++){
cin >> a[i];
}
vector<int> dp(n + 5, inf);
dp[0] = 0;
for(int i = 1; i <= n; i++){
for (int j = i; j <= n; j++){
if (j - a[i] >= 0 && j - a[i] < i)
dp[j] = min(dp[j - a[i]] + 1, dp[j]);
}
}
if (dp[n] == inf)
cout << -1 << endl;
else
cout << dp[n] << endl;
}
}
线性dp,由第 i张布告必须要覆盖掉布告板的第 i 个位置,布告不能够相互重叠,但是可以紧贴,可知,对于i>j,i<j+a[i]时,有f[j+a[i]]=min(f[j+a[i]],f[j]),然后从前往后递推即可。
F 竹鼠,宝藏与故事(待补):
后记:
好好努力吧!