zoukankan      html  css  js  c++  java
  • Zut_round 9(搜索

    A 题目传送门

    思路:在Y,M 处用 bfs 分别跑一边图,记录两个人到每个'@'的最小时间。最后再遍历一遍数组得到两个相加的结果的最小值,即答案。

    //这道题跟蓝桥杯的一道题差不多 贴个链接

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int qs=1e6+7;
     5 const int inf=0x3f3f3f3f;
     6 char C[207][207];
     7 int vis[207][207];                // 判重 
     8 int A[207][207];
     9 int B[207][207];
    10 int n,m; 
    11 struct node
    12 {
    13     int x,y;
    14     int num;
    15     node(){}                    // 用于在队列中存结构体 
    16     node(int x,int y,int num):x(x),y(y),num(num){};
    17 }t,v;
    18 queue<node> q;                    //队列 bfs 遍历
    19 int l[4]={-1,1,0,0};            // 两个数组对应移动方向 
    20 int r[4]={0,0,-1,1};
    21 void bfs(int x,int y,int S[][207])
    22 {
    23     int i,j;
    24     for(i=0;i<=n;++i)             // 重置数组 
    25     for(j=0;j<=m;++j)             // !!!这里,,,一开始写成 j<=n ,半天愣是没找出来,浪费了50分钟时间
    26     vis[i][j]=0;                // 之前一直用 memset 的,后来听说 memset 有问题就没用过 
    27     t.x=x; t.y=y; t.num=0;
    28     vis[t.x][t.y]=1;            //标记 
    29     q.push(t); 
    30     while(!q.empty())
    31     {
    32         t=q.front(); q.pop();
    33         for(i=0;i<4;++i)        //移动 
    34         {
    35             v.x=t.x+l[i];
    36             v.y=t.y+r[i];
    37             v.num=t.num+11;
    38             if(v.x<1||v.x>n||v.y<1||v.y>m||C[v.x][v.y]=='#'||vis[v.x][v.y]==1) continue;
    39             S[v.x][v.y]=v.num;    
    40             vis[v.x][v.y]=1;
    41             q.push(v);
    42         }        
    43     }
    44     return;
    45 }
    46 int main()
    47 {
    48     int i,j,k;
    49     while(cin>>n>>m)
    50     {
    51     for(i=1;i<=n;++i) cin>>C[i]+1;
    52     for(i=1;i<=n;++i)
    53     for(j=1;j<=m;++j)
    54     {
    55         if(C[i][j]=='M') bfs(i,j,A);
    56         if(C[i][j]=='Y') bfs(i,j,B);
    57     }
    58     int ans=inf;
    59     for(i=1;i<=n;++i)
    60     for(j=1;j<=m;++j)
    61     {
    62         if(C[i][j]=='@'&&A[i][j]&&B[i][j]) 
    63         ans=min(ans,A[i][j]+B[i][j]);
    64         A[i][j]=0;
    65         B[i][j]=0;
    66     }
    67     cout<<ans<<endl;    
    68     }
    69     
    70     return 0;
    71 }
    View Code

    B 题目传送门

    思路:将图看成两部分,从(1,1)和(n,m)处分别dfs跑一遍,将贴近对角线的一条线上的点设为两部分的搜索结束点(使两边搜索复杂度尽可能平均) 因为ai,j<=1e18,可用STL库函数map记录,map[x][y][temp]记录在(x,y)处异或值为temp的路径个数。

    //刚开始想dfs或bfs把整个图的每一条边都跑一边,后来被学长提醒后才明白。n,m<=20,直接从(1,1)遍历到(n,m)最大复杂度可达到 240.

    附: a^b^a=b

     1 #include<bits/stdc++.h> 
     2 using namespace std;
     3 typedef long long ll;
     4 ll A[23][23];
     5 map<ll,ll> mp[23][23];
     6 int n,m; 
     7 ll k;
     8 bool check(int x,int y)            //判断是否越界 
     9 {
    10     if(x<1||y<1||x>n||y>m) return false;
    11     return true;
    12 }
    13 ll ans=0;
    14 void dfs(int x,int y,ll temp)        //从(1,1)遍历 
    15 {
    16     if(!check(x,y)) return;
    17     if(x+y==n+1)                    //自己规定的结束点 
    18     {
    19         mp[x][y][temp]++;            //记录 
    20         return;
    21     }
    22     dfs(x+1,y,temp^A[x+1][y]);
    23     dfs(x,y+1,temp^A[x][y+1]);
    24 }
    25 void dfs1(int x,int y,ll temp)
    26 {
    27     if(!check(x,y)) return;
    28     if(x+y==n+1)
    29     {
    30         ans+=mp[x][y][temp^k^A[x][y]];        //因为终点多被异或一次,要异或回来。 
    31         return;
    32     }
    33     dfs1(x-1,y,temp^A[x-1][y]);
    34     dfs1(x,y-1,temp^A[x][y-1]);
    35 }
    36 int main()
    37 {
    38     int i,j;
    39     cin>>n>>m>>k;
    40     for(i=1;i<=n;++i) 
    41     for(j=1;j<=m;++j) cin>>A[i][j];
    42     dfs(1,1,A[1][1]);
    43     dfs1(n,m,A[n][m]);
    44     cout<<ans<<endl;
    45     return 0;
    46 }
    View Code

    D 题目传送门

    思路:设电梯在i楼,则对于在第j层的用户来说电梯耗费电力有 : (abs(i-j)+j+i)*2*A[j] ,剩下就嗯遍历,找出最优解即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int qs=1e6+7;
     5 const int inf=0x3f3f3f3f;
     6 int n,m; 
     7 int A[qs];
     8 int main()
     9 {
    10     int i,j;
    11     cin>>n;
    12     int x=0;
    13     for(i=0;i<n;++i)     cin>>A[i];
    14     int ans=inf;
    15     for(i=0;i<n;++i)
    16     {
    17         int fx=0;
    18         for(j=1;j<n;++j)
    19         {
    20             fx+=(abs(i-j)+j+i)*2*A[j];
    21         }
    22         ans=min(ans,fx);
    23     }
    24     cout<<ans<<endl;
    25     return 0;
    26 }
    View Code

    E 题目传送门

    思路:若啤酒总量小于杯子数,返回 -1。否则啤酒总量减去杯子数量再除以桶数得到平均值,平均值与桶中最小的啤酒量作比较,取小的即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 ll n,m; 
     5 int main()
     6 {
     7     ll i,j,k;
     8     cin>>n>>m;
     9     ll sum=0,x;
    10     ll y=1e18;
    11     for(i=1;i<=n;++i)
    12     {
    13         cin>>x;
    14         y=min(x,y);
    15         sum+=x;
    16     }
    17     ll ans=0;
    18     if(sum<m) ans=-1;
    19     else{
    20         ans=(sum-m)/n;
    21         ans=min(ans,y);
    22     }
    23     cout<<ans<<endl;
    24     return 0;
    25 }
    View Code

    F 题目传送门

    题目大意:求只有'a'组成的子序列个数,若子序列长度大于1,则子序列中任意 两两 'a' 在原字符串中的位置间都有至少一个 ‘b' .

    思路:设 temp 为任意相离最近两个'b'之间的 'a' 的个数+1(此处+1是因为有可能不选这个区间的 'a')。这个区间里面的 ’a' 不能相互组合。则用 temp 乘以这个区间之前已经形成的子序列个数,就是为到目前区间为止总子序列个数(包括空串),递推到字符串结束。最后再减去每个区间都不选的情况(即空串)。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int mod= 1e9+7;
     5 int n,m; 
     6 int main()
     7 {
     8     string s;
     9     cin>>s;
    10     s+='b';
    11     ll temp=1;
    12     ll ans=1;
    13     for(int i=0;i<s.size();++i)
    14     {
    15         if(s[i]=='b') 
    16         {
    17         ans=ans*temp%mod;
    18         temp=1;
    19         }
    20         if(s[i]=='a') temp++;
    21     }
    22     
    23     cout<<ans-1<<endl;
    24     return 0;
    25 }
    View Code

    5.5 补 G: 题目传送门

    树上dp,dfs一边即可。

     1 #includ<bits/stdc++.h> 
     2 using namespace std;
     3 typedef long long ll;
     4 const int inf=0x3f3f3f3f;
     5 const int qs=3e5+7;
     6 int n,m;
     7 ll dp[qs];
     8 ll w[qs];
     9 ll ans=0;
    10 struct node
    11 {
    12     ll x,y;
    13     node(){}
    14     node(ll x,ll y):x(x),y(y){};
    15 }t;
    16 
    17 vector<node> v[qs];
    18 void dfs(ll temp,ll fa)
    19 {
    20     ans=max(ans,dp[temp]);
    21     for(int i=0;i<v[temp].size();++i)
    22     {
    23         ll x=v[temp][i].x;    
    24         ll y=v[temp][i].y;    
    25         if(x==fa) continue;
    26         dfs(x,temp);
    27         ll dig=dp[x]-y;
    28         ans=max(ans,dp[temp]+dig);
    29         dp[temp]=max(dp[temp],w[temp]+dig);
    30     }
    31 }
    32 int main()
    33 {
    34     ll u,vv,k,i,j;
    35     cin>>n;
    36     for(i=1;i<=n;++i) 
    37     {
    38     cin>>w[i];     dp[i]=w[i];
    39     }
    40     for(i=1;i<n;++i) 
    41     {
    42         cin>>u>>vv>>k;
    43         v[u].push_back(node(vv,k));
    44         v[vv].push_back(node(u,k));
    45     }
    46     dfs(1,0);
    47     cout<<ans<<endl;
    48     return 0;
    49 }
    View Code

    おもしろい

  • 相关阅读:
    Linux下Java环境安装
    Go语言学习之10 Web开发与Mysql数据库
    Go语言学习之9 网络协议TCP、Redis与聊天室
    Redis入门指南之三(入门)
    Redis入门指南之一(简介)
    Go语言学习之8 goroutine详解、定时器与单元测试
    Redis入门指南之二(安装及配置)
    Go语言学习之7 接口实例、终端文件读写、异常处理
    Go语言学习之6 反射详解
    Go语言学习之5 进阶-排序、链表、二叉树、接口
  • 原文地址:https://www.cnblogs.com/Suki-Sugar/p/12824888.html
Copyright © 2011-2022 走看看