A:硬币

知识点:贪心

思路:即然每种硬币数量不限,那就可以考虑每次都使用最大的硬币来兑换(硬币值越大,个数越少),这样就能达到最优解,故让自己的总值s每次都购买s/n的张数,直到总值s为0即可。

参考代码:

#include <bits/stdc++.h>
using namespace std;
int n,s,ans;
int main() {    
    cin>>n>>s;
    if(s<=n){
        cout<<1;
        return 0;
    }
    while(s){//有钱就需要硬币 
        int cnt=s/n;//看看s能买几张n元硬币
        ans+=cnt;
        s-=cnt*n;
        if(!s)break;
        n--;
    }
    cout<<ans;
    return 0;
}

B:完美字符串

知识点:字符串、结构体排序

思路:题目说明不在乎字母大小写,那就全部处理成小写字母或者大写字母,统计看看那个字母出现的次数最多,对字母进行排序。那就可以想到使用结构体来进行存储,成员有两个,出现的次数n和字符c,最后按照出现的次数进行排序,进而累加求和即可。

参考代码:

#include<bits/stdc++.h>
using namespace std;
struct node {
    int n;
    char c;
    bool operator<(const node & b) const {
        return n>b.n;
    }
} a[27];
string s;
int ans;
int main() {
    cin>>s;
    for(int i=0; i<s.size(); i++) {
        if(s[i]>='A'&&s[i]<='Z')s[i]+=32;
        a[s[i]-'a'+1].n++;
        a[s[i]-'a'+1].c=s[i];
    }
    sort(a+1,a+1+26);
    for(int i=1,cnt=26; i<=26; i++,cnt--) {
        if(a[i].c>='a'&&a[i].c<='z') {
            ans+=cnt*a[i].n;
        }
    }
    cout<<ans;
    return 0;
}

C:守门骑士

知识点:广度优先搜索

思路:考虑到贝西把灌木交给骑士,那就遍历每个灌木的位置,然后进行广搜,分别统计到达贝西的位置至少需要几步,统计到达骑士的位置至少需要几步,擂台比较其最小值即可。

参考代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,a[101][101],stx,sty,qix,qiy,ans=INT_MAX,posx,posy;
int d[][2]= {{0,1},{0,-1},{1,0},{-1,0}};
bool v[101][101];
struct node {
    int x,y,s=0;
};
int bfs(int x,int y){
    int f1=0,f2=0,ans1=0,ans2=0;
    memset(v,0,sizeof v);v[x][y]=1;
    node no;no.x=x;no.y=y;no.s=0;
    queue<node> q;q.push(no);
    while(!q.empty()){
        node t=q.front();q.pop();
        if(f1&&f2) return ans1+ans2;
        if(t.x==stx&&t.y==sty&&!f1){
            f1=1;
            ans1=t.s;
        }
        if(t.x==qix&&t.y==qiy&&!f2){
            f2=1;
            ans2=t.s;
        }
        for(int i=0;i<4;i++){
            int xx=t.x+d[i][0],yy=t.y+d[i][1];
            if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&1!=a[xx][yy]&&!v[xx][yy]){
                v[xx][yy]=1;
                node nod;nod.x=xx;nod.y=yy;nod.s=t.s+1;
                q.push(nod);
            }
        }
    }
    return INT_MAX;
}
int main() {
    cin>>n>>m;
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            cin>>a[i][j];
            if(a[i][j]==2)stx=i,sty=j;
            if(a[i][j]==3)qix=i,qiy=j;
        }
    }
    for(int i=1; i<=n; i++) 
        for(int j=1; j<=m; j++) 
            if(a[i][j]==4) 
                ans=min(ans,bfs(i,j));
    if(ans==INT_MAX) cout<<-1;
    else cout<<ans;
    return 0;
}

D:骨头收藏家

知识点:动态规划、背包

思路:令d[j]表示体积为j时最大的骨头价值。则

当不收集第i个骨头时,其值就是上一个值继承下来,d[j]=d[j];

当收集第i个骨头时,其值就是体积减少第i个骨头的体积加上第i个骨头的价值d[j]=d[j-weight[i]]+val[i];

综合考虑取其最大值d[j]=max(d[j],d[j-weight[i]]+val[i])即可。

注意多组数据需要每轮清空。

参考代码:

#include<bits/stdc++.h>
using namespace std;
int t,n,v,val[1001],weight[1001],d[1001];
int main(){
    cin>>t;
    while(t--){
        cin>>n>>v;
        memset(d,0,sizeof d);
        for(int i=1;i<=n;i++)cin>>val[i];
        for(int i=1;i<=n;i++)cin>>weight[i];
        for(int i=1;i<=n;i++)
            for(int j=v;j>=weight[i];j--)
                d[j]=max(d[j],d[j-weight[i]]+val[i]);
        cout<<d[v]<<endl;
    }
    return 0;
}
Copyright ©图灵之星 2024,转载需注明出处该文件修订时间: 2025-04-19 21:37:07

results matching ""

    No results matching ""