zoukankan      html  css  js  c++  java
  • 牛客算法周周练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
  • 相关阅读:
    Java学习开篇
    《我的姐姐》
    世上本无事,庸人自扰之
    这48小时
    补觉
    淡定
    es java api 设置index mapping 报错 mapping source must be pairs of fieldnames and properties definition.
    java mongodb groupby分组查询
    linux 常用命令
    mongodb too many users are authenticated
  • 原文地址:https://www.cnblogs.com/overrate-wsj/p/12983851.html
Copyright © 2011-2022 走看看