• 牛客算法周周练7-题解


    链接:https://ac.nowcoder.com/acm/contest/5927#question

    A - 收集纸片

    题意:

    在二维坐标中有$n$个点需要你依次到达并最后返回起点,求最短路程

    思路:

    典型的$TSP$旅行商问题,因为$n$最大只有$10$,所以我们可以用$DFS$遍历所有可能的情况,时间复杂度为$O(10!)$

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #define inf 0x3f3f3f3f
     using namespace std;
     typedef long long ll;
     int x,y,sx,sy,n,ans;
     int vis[11];
     struct node{
         int x,y;
     }a[11];
     void dfs(int cnt,int num,int dis)
     {
         if(cnt==n){
             ans=min(ans,dis+abs(a[num].x-sx)+abs(a[num].y-sy));
             return;
         }
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                int ret=dis+abs(a[num].x-a[i].x)+abs(a[num].y-a[i].y);
                vis[i]=1;
                dfs(cnt+1,i,ret);
                vis[i]=0;
            } 
        }
     }
     int main()
     {
         int t;
         cin>>t;
         while(t--){
             memset(vis,0,sizeof(vis));
             ans=inf;
             cin>>x>>y>>sx>>sy;
            cin>>n;    
            for(int i=1;i<=n;i++)
                cin>>a[i].x>>a[i].y;
            for(int i=1;i<=n;i++){
                vis[i]=1;
                dfs(1,i,abs(a[i].x-sx)+abs(a[i].y-sy));
                vis[i]=0;
            }
            cout<<"The shortest path has length "<<ans<<endl;
         }
         return 0;
     }
    View Code

    C -  Rabbit的工作(1)

    题意:

    一共有$n$天,如果连续工作第$i$天需要耗费精力$i$,同时根据安排你也可以休息,不消耗精力,在消耗精力小于等于$k$的情况下,问你最多能工作几天

    思路:

    定义$dp[i][j][k]$为,过去$i$天,当前已经连续工作$j$天,总计工作$k$天需要消耗的精力

    如果选择休息则状态转移方程为$dp[i+1][0][k]=min(dp[i][j][k],dp[i+1][0][k])$

    在可以工作的情况下,转态转移方程为$dp[i+1][j+1][k+1]=min(dp[i+1][j+1][k+1],dp[i][j][k]+(j+1))$

    最后,因为内存限制,第一维可以用滚动数组节约空间

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #define inf 0x3f3f3f3f
     using namespace std;
     const int N=405;
     int dp[2][N][N];
     string s;
     int main()
     {
         int n,x,ans=0;
         cin>>n>>x;
         dp[0][0][0]=0;
         int now=0;
         cin>>s;
        for(int i=1;i<=n;i++){
            memset(dp[now^1],inf,sizeof(dp[now^1]));
            for(int j=0;j<i;j++){
                for(int k=j;k<i;k++){
                    dp[now^1][0][k]=min(dp[now][j][k],dp[now^1][0][k]);
                    if(s[i-1]=='1')
                        dp[now^1][j+1][k+1]=min(dp[now][j][k]+j+1,dp[now^1][j+1][k+1]);
                }
            }
            now^=1;
        }
        for(int i=0;i<=n;i++){
            for(int j=i;j<=n;j++){
                if(dp[now][i][j]<=x) 
                    ans=max(ans,j);
            }
        }
        cout<<ans;
        return 0;
    }
    View Code

     D - 华华和月月逛公园

    题意:

    给一张$n$个点$m$条边的无向图,让你求出非关键边的个数,非关键边的定义为去掉这条边后,依旧可以从$1$号点出发,到达图中所有点

    思路:

    转换题意后,就是求非桥边的个数,直接套用$tarjan$求桥的模板即可

    #include<iostream>
    #include<algorithm>
    #include<vector>
     using namespace std;
     const int maxn=1e5+10;
     vector<int> a[maxn];
     int ans=0,vis[maxn];
     void dfs(int tim,int fa,int u)
     {
        vis[u]=tim;
         for(int i=0;i<a[u].size();i++){
             int v=a[u][i];
             if(v==fa) continue;
             if(vis[v]){
                 ans+=tim+1-vis[v];
                 vis[v]=tim+1;
                 continue;
             }
             dfs(tim+1,u,v);
         }
     }
     int main()
     {
         int n,m,u,v;
         cin>>n>>m;
         for(int i=1;i<=m;i++){
             cin>>u>>v;
             a[u].push_back(v);
             a[v].push_back(u);
         }
        dfs(1,1,1);
        cout<<ans<<endl;
     }
    View Code

     E - 数字比较

    题意:

    给两个数字$x$与$y$,比较$x^{y}$跟$y^{x}$的大小

    思路:

    将$x^{y}$跟$y^{x}$化成幂次相同的形式,在比较两数的底数大小即可

    #include<algorithm>
    #include<iostream>
     using namespace std;
     typedef long long ll;
     int main()
     {
         ll x,y;
         cin>>x>>y;
         if(y>=x){
             if(pow(x,1.0*y/x)>y) cout<<">";
             else if(pow(x,1.0*y/x)==y) cout<<"=";
             else cout<<"<";
         }
        else{
            if(pow(y,1.0*x/y)>x) cout<<"<";
             else if(pow(y,1.0*x/y)==x) cout<<"=";
             else cout<<">";
        }
     }
    View Code
  • 相关阅读:
    Nginx 禁止IP访问
    Nginx服务优化详解
    adb不响应
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    【翻译】Android避免内存泄露(Activity的context 与Context.getApplicationContext)
    内存泄露情况
    AndroidManifest笔记
    RecyclerView设置verticalSapcing等
    Fragment回调顺序及getActivity()为NullPointerException解决方法
    git tag
  • 原文地址:https://www.cnblogs.com/overrate-wsj/p/12983851.html
Copyright © 2020-2023  润新知