A:第一次,第二次,成交!

知识点:模拟、枚举

思路:先把每个人出的价格从小到大排序。从最小价格开始枚举。显然后面的人出的价格都比当前价格大。

答案就是当前价格*(m-当前位置+1)的最大值。再记录一下去最大值时的价格就好啦。注意n和m的大小关系。

参考代码:

#include <bits/stdc++.h>
using namespace std;
int n,m,a[1005],maxn,ans;
int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++)
        cin>>a[i];
    sort(a+1,a+m+1);
    for(int i=m;i>=1;i--)
        if(a[i]*(m-i+1)>=maxn && m-i+1<=n)
            maxn=a[i]*(m-i+1),ans=a[i]; 
    cout<<ans<<" "<<maxn;
    return 0 ;
}

B:障碍迷宫

知识点:搜索、递推

思路:基本搜索类题目,从起点sx,sy进行搜索,若是到达了终点,则统计答案,返回,然后进行四个方向的枚举,注意不能越界,曾经未被访问并且还不能是障碍物,那么此时就可以访问一下该位置,进行深搜,结束了不要忘记在撤销掉此位置就可以了。

参考代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,t,ans;//n行m列t个障碍
int sx,sy,ex,ey;//起点和终点坐标
int x,y;//障碍的位置 
int a[11][11];//地图 
bool v[11][11];//标记 
int d[][2]={{0,1},{0,-1},{1,0},{-1,0}};
void dfs(int x,int y){
    if(x==ex && y==ey){
        ans++;
        return;
    }
    for(int i=0;i<4;i++){
        int xx=x+d[i][0],yy=y+d[i][1];
        if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&!v[xx][yy]&&!a[xx][yy]){
            v[xx][yy]=1;
            dfs(xx,yy);
            v[xx][yy]=0;
        }
    } 
} 
int main(){
    cin>>n>>m>>t>>sx>>sy>>ex>>ey;
    for(int i=1;i<=t;i++){
        cin>>x>>y;
        a[x][y]=1; 
    } 
    v[sx][sy]=1;//起点打标记 
    dfs(sx,sy);//从sx,sy出发
    cout<<ans; 
    return 0;
}

C:特殊的质数肋骨

知识点:质数、搜索

思路:首先,我们看到这题,第一个想法一定是枚举,然而这并不现实,所以我们想到枚举每一位,来构造质数。于是我们可以想到搜索。然后我们知道,只有开头能够出现2,5,其它数位不可能是偶数和5,所以枚举每一位数字的时候自然想到剪枝手段:跳过2,4,5,6,8.此外,另一个剪枝就是生成的数是否是质数,可以写个判断函数。

代码:

#include<bits/stdc++.h>
using namespace std;
int n;
bool pd(int x){
    for(int i=2;i*i<=x;i++)
        if(x%i==0)return 0;
    return 1;
}
void dfs(int s,int x){
    if(s>=n){
        cout<<x<<endl;
        return;
    }
    if(pd(x*10+1)) dfs(s+1,x*10+1);
    if(pd(x*10+3)) dfs(s+1,x*10+3); 
    if(pd(x*10+7)) dfs(s+1,x*10+7); 
    if(pd(x*10+9)) dfs(s+1,x*10+9); 
}
int main(){
    cin>>n;
    dfs(1,2);
    dfs(1,3);
    dfs(1,5);
    dfs(1,7);
    return 0;
}

D:聚会

知识点:最短路、Dijkstra

思路:

  • 我们首先想到的是从每个点都求一遍到终点的最短路,这样会加大时间复杂度。
  • 所以,我们可以反向建图,直接把单终点最短路转为单源最短路,只需要跑两次最短路算法,显然是稳过的。

参考代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,x,ans;//n头牛 m道路 x编号举行派对
int g[1001][1001],f[1001][1001],dis[1001],Dis[1001];
bool vis[1001];
struct node{
    int v,w;
};
void dijkstra(){
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
        dis[i]=g[x][i];
    dis[x]=0;vis[x]=1;
    for(int i=1;i<n;i++){
        int minn=INT_MAX,pos=0;
        for(int j=1;j<=n;j++)
            if(!vis[j]&&minn>dis[j])
                minn=dis[j],pos=j;
        if(!pos)break;vis[pos]=1;
        for(int j=1;j<=n;j++)
            dis[j]=min(dis[j],dis[pos]+g[pos][j]);
    }
} 
void Dijkstra(){
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
        Dis[i]=f[x][i];
    Dis[x]=0;vis[x]=1;
    for(int i=1;i<n;i++){
        int minn=INT_MAX,pos=0;
        for(int j=1;j<=n;j++)
            if(!vis[j]&&minn>Dis[j])
                minn=Dis[j],pos=j;
        if(!pos)break;vis[pos]=1;
        for(int j=1;j<=n;j++)
            Dis[j]=min(Dis[j],Dis[pos]+f[pos][j]);
    }
} 
int main(){
    cin>>n>>m>>x;
    memset(g,0x3f3f3f3f,sizeof(g));
    memset(f,0x3f3f3f3f,sizeof(f));
    for(int i=1;i<=n;i++)g[i][i]=0,f[i][i]=0;
    for(int i=1;i<=m;i++){
        int a,b,c;
        cin>>a>>b>>c;
        g[a][b]=c;//从a到b距离为c 
        f[b][a]=c;//从b到a距离为c 
    } 
    dijkstra();
    Dijkstra();
    for(int i=1;i<=n;i++)
        ans=max(ans,dis[i]+Dis[i]); 
    cout<<ans;
    return 0;
}
Copyright ©图灵之星 2024,转载需注明出处该文件修订时间: 2025-05-17 22:16:55

results matching ""

    No results matching ""