sicily考试模拟题-1003相连的1 1004isDAG? 1005相邻的数 1006单词变换

来源:互联网 发布:网络侦探 贝尔菲兽 编辑:程序博客网 时间:2024/05/18 09:15

1003相连的1


题目描述

对于一个01矩阵A,求其中有多少片连成一片的1. 每个1可以和上下左右的1相连.请为下面的Solution类实现解决这一问题的函数countConnectedOnes,函数参数A为给出的01矩阵,A的行数和列数均不大于1000. 函数的返回值是问题的答案.class Solution {public:    int countConnectedOnes(vector<vector<char>>& A) {    }};例1:A=100010001答案为3.2:A=110101011110答案为2.

解题思路

考查BFS,通过BFS寻找一个点所连接的所有点,queue记录同一层的节点。

解题代码

#include <iostream>#include <vector>#include <queue>#include <algorithm>using namespace std;class Node{  public:    int x;    int y;    Node(int i,int j){x=i;y=j;}};class Solution {public:  //定义四个方向  int dir[4][2]={  {0, 1}, {1, 0},  {0, -1}, {-1, 0}  };    bool isValid(vector<std::vector<char> >&A,Node &node){    int m=A.size();    int n=A[0].size();    if (node.x<0 || node.x>=m ) return false;    if (node.y<0 || node.y>=n ) return false;    if (A[node.x][node.y]!='1') return false;    return true;  }  void BFS(vector<vector<char> >&A,vector<vector<bool> >&B,Node &node){    queue<Node>que;    que.push(node);    B[node.x][node.y]=true;    while(!que.empty()){      Node p = que.front();      que.pop();      for (int i = 0; i < 4; ++i)      {        Node pNext=Node(p.x+dir[i][0],p.y+dir[i][1]);        // if (Vw == Vd){//找到终点了!       //              //把路径记录,这里没给出解法       //              return true;//返回      //          }          if (isValid(A,pNext)&&B[pNext.x][pNext.y]==false ){          que.push(pNext);          B[pNext.x][pNext.y]=true;        }      }    }  }    int countConnectedOnes(vector<vector<char> >& A) {         //空数组         int m=A.size();         if (m==0) return 0;         int n=A[0].size();         if(n==0) return 0;         //初始化节点访问矩阵         vector<std::vector<bool> > B(m,std::vector<bool> (n,false) );         int count=0;         for (int i = 0; i < m; ++i)         {          for (int j = 0; j < n; ++j)          {            if(A[i][j]=='1' && B[i][j]==false){              count ++;              Node node=Node(i,j);              BFS(A,B,node);            }          }         }         return count;      }};int main(){   vector<vector<char> >migong(3,vector<char>(4));    migong[0][0]='1';migong[0][1]='1';migong[0][2]='0';migong[0][3]='1';    migong[1][0]='0';migong[1][1]='1';migong[1][2]='0';migong[1][3]='1';    migong[2][0]='1';migong[2][1]='1';migong[2][2]='1';migong[2][3]='0';   Solution sol;   int res=sol.countConnectedOnes(migong);   cout << "result is ->"<<res << endl;    return 0;}

1004 isDAG?


题目描述

在图论中,如果一个有向图从任意顶点出发无法经过若干条边回到该点,则这个图是一个有向无环图(Directed Acyclic Graph,DAG). 对于一个n个节点的有向图(节点编号从0到n-1),请判断其是否为有向无环图.图的节点数和边数均不多于100000.请为下面的Solution类实现解决上述问题的isDAG函数,函数参数中n为图的节点数,edges是边集,edges[i]表示第i条边从edges[i].first指向edge[i].second. 如果是有向无环图返回true,否则返回false.class Solution {public:       bool isDAG(int n, vector<pair<int, int>>& edges) {    }};例1:n = 3,edges = {(0, 1), (0, 2)},函数应返回true.例2:n = 2,edges = {(0, 1), (1, 0)},函数应返回false.注意:你只需要提交Solution类的代码,你在本地可以编写main函数测试程序,但不需要提交main函数的代码. 注意不要修改类和函数的名称.

解题思路

先建立图的vector结构,再dfs检索有向图中有没有环

解题代码

class Solution {public:    bool isDAG(int n, vector<pair<int, int>>& edges) {      //构造图向量-有向图      std::vector< std::vector<int> > graph(n);      for (int i = 0; i < edges.size(); ++i)      {        graph[edges[i].first].push_back(edges[i].second);      }      //记录已访问节点      std::vector<bool> visited(n,false);      //记录当前路径上的节点      std::vector<bool> onpath(n,false);      //遍历所有的图中节点,判断当前有没有回路      for (int i = 0; i < n; ++i)      {        if(has_circle(graph,i,visited,onpath))          return false;      }      return true;    }    bool has_circle(std::vector<std::vector<int> > &graph, int node,std::vector<bool> &visited,std::vector<bool> &onpath ){      if (visited[node]) return false;      onpath[node]=visited[node]=true;      for (int i = 0; i < graph[node].size(); ++i)      {        //onpath是指向路径上的节点--回路;has_circle是dfs思想        if(onpath[ graph[node][i] ]|| has_circle(graph,graph[node][i],visited,onpath) )          return true;      }      onpath[node]=false;      return false;    }};

1005相邻的数


题目描述

从数列A[0], A[1], A[2], ..., A[N-1]中选若干个数,要求相邻的数不能都选,也就是说如果选了A[i], 就不能选A[i-1]和A[i+1]. 求能选出的最大和.1 <= N <= 100000, 1 <= A[i] <= 1000请为下面的Solution类实现解决上述问题的函数maxSum,函数参数A是给出的数列,返回值为所求的最大和.class Solution {public:    int maxSum(vector<int>& A) {    }};例1:A = {2, 5, 2},答案为5.2:A = {2, 5, 4},答案为6.

解题思路

动态规划题目,写出状态转移方程即可

解题代码

#include <iostream>#include <vector>#include <algorithm>using namespace std;class Solution {public:    int maxSum(vector<int>& A) {        if (A.size()==0 ) return 0;        std::vector<int> f(A.size());        f[0]=A[0];        f[1]=A[0]>A[1]?A[0]:A[1];        for (int i = 2; i < A.size(); ++i)        {            //            f[i]=f[i-1]>(A[i]+f[i-2])?f[i-1]:(A[i]+f[i-2]);        }        return f[A.size()-1];    }};int main(int argc, char const *argv[]){    Solution sol;    cout<<"-------------------------------------------"<<endl;    int arr1[]={2,5,2}; int arr2[]={2,5,4};     vector<int>A(begin(arr1),end(arr1));    vector<int>B(begin(arr2),end(arr2));    cout<<"solutionA is :"<<sol.maxSum(A)<<endl;    cout<<"solutionB is :"<<sol.maxSum(B)<<endl;    // cout<<"solution is :"<<sol.F(2,3)<<endl;    // cout<<"solution is :"<<sol.F(10,10)<<endl;    cout<<"-------------------------------------------"<<endl;    return 0;}

1006单词变换


题目描述

对于两个只含有小写英文字母(’a’-‘z’)的单词word1和word2,你可以对word1进行以下3种操作:1) 插入一个字母;2) 删除一个字母;3) 替换一个字母.请计算将word1变换成word2的最少操作数.word1和word2的长度均不大于1000.请为下面的Solution类实现解决上述问题的函数minDistance,函数的参数word1和word2为给出的两个单词,返回值为所求最少操作数.class Solution {public:    int minDistance(string word1, string word2) {       }};例1:word1 = “sunny”, word2 = “snowy”,返回值为3.2:word1 = “abc”, word2 = “ac”,返回值为1.

解题思路

经典动规。
使用一个二维数组dp[m][n] 来维护状态,它表示从一个长度为m的word1变换到一个长度为n的word2所需要的最少操作数。
每次将两个单词往前看一个字母,那么有如下两种可能。

两个字母相同。那么,显然不需要做更改操作,有 dp[m][n] = dp[m - 1][n - 1]
两个字母不相同,那么,需要考虑如下三种操作:
如果word1的当前字母和word2的前一个字母相同,那么说明word1需要做1次插入操作,即dp[m][n] = 1 + dp[m][n - 1];
如果word1的前一个字母和word2的当前字母相同,那么说明word1需要做1次删除操作,即dp[m][n] = 1 + dp[m - 1][n];
如果word1的前一个字母和word2的前一个字母相同,那么说明word1需要做1次替换操作,即dp[m][n] = 1 + dp[m - 1][n].
由于要找的是最小的操作次数,所以,在第二种情况下,取三种子情况的最小值。

解题代码

class Solution {
public:
int triMin(int a, int b, int c) {
int tempA = min(a, b);
int tempB = min(b, c);
return min(tempA, tempB);
}

int minDistance(string word1, string word2) {    int m = word1.size();    int n = word2.size();    int dp[m + 1][n + 1];    for (int i = 0; i <= m; ++i) {        for (int j = 0; j <= n; ++j) {            if (i == 0) dp[i][j] = j;            else if (j == 0) dp[i][j] = i;            else if (word1[i - 1] == word2[j - 1])                dp[i][j] = dp[i - 1][j - 1];            else                 dp[i][j] = 1 + triMin(dp[i][j - 1],     // insert                                   dp[i - 1][j],     // remove                                   dp[i - 1][j - 1]); // replace                    }    }    return dp[m][n];   }

};