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
  • 相关阅读:
    微信 token ticket jsapi_ticket access_token 获取 getAccessToken get_jsapi_ticket方法
    PHP 日志 记录 函数 支持 数组 对象 新浪 sae 环境 去掉 空格 换行 格式化 输出 数组转字符串
    原生 原始 PHP连接MySQL 代码 参考mysqli pdo
    PHP 数字金额转换成中文大写金额的函数 数字转中文
    使用PHPMailer发送带附件并支持HTML内容的邮件
    设置输出编码格式 header 重定向 执行时间 set_time_limit 错误 报告 级别 error_reporting
    html5 bootstrap pannel table 协议 公告 声明 文书 模板
    指向指针的指针
    二级指针
    c语言:当指针成为参数后
  • 原文地址:https://www.cnblogs.com/overrate-wsj/p/12983851.html
Copyright © 2011-2022 走看看