京东2019校招在线考试(算法岗)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hqh131360239/article/details/82588311

思路:感觉还是题目描述有点问题。

错误思路:题意没有读清,一直以为S串去替换T串,如测试数据(ababcb替换后xyxyxy,与xyx进行匹配,大眼一看不错结果就是三个,然后突然想到最长公共子序列的出现次数,我擦,敲出代码发现就是结果不对,尴尬,什么原因,找了半天没有发现错误何在,最后发现xyxyxy去匹配xyx不是3是4,(xyxyxy)(xyxyxy)(xyxyxy)(xyxyxy))。噢噢,一下回到解放前。那估计就是题目理解错误了。

最长公共子序列及个数:求最长是一个很简单的dp,但是求最长的个数,以前没有接触过,若a[i]!=b[j]的时候,判一下f[i][j]和f[i-1][j],f[i][j-1]分别相不相等,如果相等就加上对应的方案数,再判和f[i-1][j-1]是否相等,相等就再减去[i-1][j-1]的方案数;a[i]==b[j]的时候,用[i-1][j-1]的方案数,然后如果f[i-1][j]或者[i][j-1]和f[i][j]相等的话,也加上对应的方案数。(注意必要时,可以使用滚动数组进行转态压缩)

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#define mod 100000000
using namespace std;
string a,b;
int f[5005][5005],g[5005][5005];
int main(){
    cin>>a>>b;
    int l1=a.length()-1,l2=b.length()-1;
    a=' '+a,b=' '+b;
    for(int i=0;i<=l1;i++)g[i][0]=1;
    for(int i=0;i<=l2;i++)g[0][i]=1;
    for(int i=1;i<=l1;i++)
      for(int j=1;j<=l2;j++)
        {
              if(a[i]==b[j])
              {
                  f[i][j]=f[i-1][j-1]+1;
                g[i][j]=g[i-1][j-1];
                if(f[i][j]==f[i][j-1])g[i][j]=(g[i][j]+g[i][j-1])%mod;
                if(f[i][j]==f[i-1][j])g[i][j]=(g[i][j]+g[i-1][j])%mod;
            }
              else
              {
                  f[i][j]=max(f[i-1][j],f[i][j-1]);
                  if(f[i][j]==f[i-1][j])g[i][j]=(g[i][j]+g[i-1][j])%mod;
                if(f[i][j]==f[i][j-1])g[i][j]=(g[i][j]+g[i][j-1])%mod;
                if(f[i][j]==f[i-1][j-1])g[i][j]-=g[i-1][j-1],g[i][j]=(g[i][j]+mod)%mod;
            }
        }
    cout<<f[l1][l2]<<endl<<g[l1][l2]%mod;
    return 0;
}

正确:看了一下讨论区,看不懂哎,运行了一下代码,搞得我想吐血。什么情况,对应S和T串都需要编码,然后还是连续子串,编码竟然是这样编码的XYX==010,ababcb不能直接编码,只能截取3个一段落,aba、bab、abc、bcb,编码分别是010、010、012、010,看出什么了吗?竟然是按照子串的下标进行编码,如aba,第二个a在下标0的时候出现过了。好吧,已哭晕在厕所(貌似这个还不是100%通过,超时)

#直接上讨论群区的代码了
def get(d,key,value):
    if(key not in d):
        d[key] = value
    return d[key]
def solve(S, T):
    Tflag = []
    tempdict = dict()
    for i in range(len(T)):
        Tflag.append(get(tempdict,T[i],i))
    #得到对应索引列表
    #print(Tflag)
    count = 0
    for i in range(0,len(S)-len(T)+1):
        string = S[i:i+len(T)]
        tempdict = dict()
        Sflag = []
        for j in range(len(string)):
            Sflag.append(get(tempdict,string[j],j))
        #print(Sflag)
        if Tflag == Sflag:
            count += 1
    return count
print(solve("ababcb","xyx"))

思路:一笔画问题,只要整个图互联互通即可,还不对,还不用使用欧拉回路判定(每个边只能访问一次)。感觉只要是一个连通图即可,bfs+邻接矩阵判定即可。看了一下测试数据,同一集合不能相连接,不同集合必须要直接相连接。又凉凉了。

看了一下讨论区,感慨一下,数学真强大,把与顶点A不相连接的顶点和与顶点A相连接的顶点找出来;与顶点A不相连接的顶点一定在同一集合,相连的一定不能在同一集合;注意题目要求,那么只需要两次for循环遍历即可,与A不相连接的顶点(同一集合)必须和A相连接的顶点都相连接(不同集合),这样才符合题意。

package com;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class hqh1 {
    public static class Node{
        public int value;
        public ArrayList<Node> nexts;
        public boolean pass;
        public Node(int value){
            this.value = value;
            nexts = new ArrayList<>();
            pass = false;
        }
    }
    public static void process(Scanner in){
        int n = in.nextInt();
        int m = in.nextInt();
        HashMap<Integer, Node> map = new HashMap<>();
        for(int i = 0; i < n; i++){
            map.put(i+1, new Node(i+1));   //建立索引,n个下标对应顶点
        }
        for(int i = 0; i < m; i++){
            int f = in.nextInt();
            int s = in.nextInt();
            Node nf = map.get(f);      //根据下标,获取顶点
            Node ns = map.get(s);
            nf.nexts.add(ns);         //对应顶点,添加相连接的顶点
            ns.nexts.add(nf);
        }
        Node n1 = map.get(1);          //取出顶点1
        map.remove(1);
        List<Node> xl = n1.nexts;      //与顶点1相关的顶点
        List<Node> nxl = new ArrayList<>();
        for (Map.Entry<Integer, Node> entry : map.entrySet()) {
            if(!xl.contains(entry.getValue())){  //与顶点1无关的顶点
                nxl.add(entry.getValue());
            }
        }
        //判断,按照要求,与顶点1无关的顶点一定在同一集和,并且与其它顶点都相连
        boolean pan = false;
        for(Node node : nxl){   //无关顶点
            for(Node node1: xl){  //有关顶点
               if(!node.nexts.contains(node1)){
                    pan = true;
                    break;
                }
            }
        }
        if(pan){
            System.out.println("No");
        }else{
            System.out.println("Yes");
        }
    }
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        for(int i = 0; i < n; i++){
            process(in);
        }
    }
}
#include<stdio.h>
#include <algorithm>
#include<vector>
#include<iostream>
using namespace std;
int main(){
    int T,n,m,x,y;
    scanf("%d",&T);

    while(T--){
       vector<vector<int> >List(1005);
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++){
            scanf("%d%d",&x,&y);
            List[x].push_back(y);
            List[y].push_back(x);
        }
        //与顶点1相连的顶点
        vector<int> yes=List[1];
        vector<int> no;
        //找与与顶点1不相连的顶点
        for(int i=2;i<=n;i++){
            if(find(yes.begin(),yes.end(),i)==yes.end()){  //没找到
                no.push_back(i);
            }
        }
        //判断
        int flag=0;
        for(int i=0;i<no.size();i++){       //顶点no[i]
            for(int j=0;j<yes.size();j++){  //顶点yes[j]
                //判断顶点no[i]是否连接顶点yes[j]
                if(find(List[no[i]].begin(),List[no[i]].end(),yes[j])==List[no[i]].end()){ //没找到
                    flag=1;
                    break;
                }
            }
            if(flag==1) break;
        }
        printf("%s\n",flag?"No":"Yes");
    }
}
/*
2
5 7
1 3 1 5 2 3 2 5 3 4 4 5 3 5
4 3
1 2 2 3 3 4
*/

猜你喜欢

转载自blog.csdn.net/hqh131360239/article/details/82588311
今日推荐