3.24

模拟,最短路,dp

图片平滑器

thinking

好好读题,然后模拟

solution

class Solution {
public:
    int dx[9]={-1,-1,-1,0,0,1,1,1,0};
    int dy[9]={-1,0,1,-1,1,-1,0,1,0};
    vector<vector<int>> imageSmoother(vector<vector<int>>& img) {
        int m=img.size();
        int n=img[0].size();
        vector<vector<int>>imgg(m,vector<int>(n,0));
        for(int i=0;i<m;++i)
            for(int j=0;j<n;++j) {
                int sum=0;
                int count=0;
                for(int k=0;k<9;++k) {
                    int x=dx[k]+i,y=dy[k]+j;
                    if(x<m&&y<n&&x>=0&&y>=0) {
                        sum+=img[x][y];
                        ++count;
                    }
                }
                    sum/=count;
                    imgg[i][j]=sum;
            }
        return imgg;
    }
};

除法求值

thinking

我们将每一个条件建立成有向边,边权就是题目给出的倍数关系,我们统计出所有的节点之间的距离,直接进行查询即可。我们采用floyd进行求解(ps:一定要认真读题,不认真读题必被暴打)

solution

class Solution {
public:
    vector<double> calcEquation(vector<vector<string>>& e, vector<double>& v, vector<vector<string>>& qq) {
        unordered_map<string,int> hash;
        int id=0;
        for(auto &ee:e) {
            if(!hash.count(ee[0])) hash[ee[0]]=id++;
            if(!hash.count(ee[1])) hash[ee[1]]=id++;
        }
        vector<vector<double>>a(id,vector<double>(id,-1));
        int n=e.size();
        for(int i=0;i<n;++i) {
            vector<string> &ee=e[i];
            a[hash[ee[0]]][hash[ee[1]]]=v[i];
            a[hash[ee[1]]][hash[ee[0]]]=1.0/v[i];
        }
        //flyod
        for (int k = 0; k < id; k++) {
            for (int i = 0; i < id; i++) {
                for (int j = 0; j < id; j++) {
                    if (a[i][k] > 0 && a[k][j] > 0) {
                        a[i][j] = a[i][k] * a[k][j];
                    }
                }
            }
        }
        for(int i=0;i<id;++i) a[i][i]=1.0;
        vector<double> ans;
        for(auto &q:qq) {
            double cnt=-1.0;
            if(hash.count(q[0])&&hash.count(q[1])) {
                if(a[hash[q[0]]][hash[q[1]]]>0) {
                    cnt=a[hash[q[0]]][hash[q[1]]];
                }
            }
            ans.push_back(cnt);
        }
        return ans;
    }
};

正则表达式匹配

thinking

线性dp,我们定义\(f[i][j]\),来表示s的前i个字符,能否匹配p的前j个字符,因此,我们可以写出状态转移方程:

\[考虑到f[0][0]=true,\\ 1、p[j]='.',p[i+1][j+1]=true\\ 2、p[j]=字母,if(p[j]==s[i])\quad f[i+1][j+1]=true\\ 3、p[j]='*',多种选择:当我们选择不匹配的时候,f[i][j+1]=true\\ 当我们匹配的时候,\\if\quad p[j-1]='.'\quad,f[i+1][j]=true表示我们要么匹配1个s中的字符,要么匹配无穷个字符,从两种情况来说,都可以相当于我们没有用这个*\\ if\quad p[j-1]=字母,且前面一个字符也相同,即是,p[j-1]=s[i],有f[i+1][j]=true \]

solution

class Solution {
    bool f[21][31];
public:
    bool isMatch(string s, string p) {
        memset(f,false,sizeof(f));
        int n=s.size(),m=p.size();
        f[0][0]=true;
        for(int i=0;i<=n;++i) {
            for(int j=0;j<m;++j) {
                if(f[i][j]==true) {
                    if(p[j]=='.'&&i!=n) f[i+1][j+1]=true;
                    if(p[j]<='z'&&p[j]>='a'&&i!=n&&s[i]==p[j])
                        f[i+1][j+1]=true;
                    if(j<m-1&&p[j+1]=='*')
                        f[i][j+2]=true;
                    if(p[j]=='*') {
                        f[i][j+1]=true;//当前可以不匹配
                        if(p[j-1]=='.'&&i!=n) {
                            f[i+1][j]=true;
                        }
                        if(p[j-1]<='z'&&p[j-1]>='a'&&i!=n&&s[i]==p[j-1]) {
                            f[i+1][j]=true;
                        }
                    }
                }
            }
        }
        return f[n][m];
    }
};
posted @ 2022-03-24 23:42  圣道  阅读(108)  评论(0)    收藏  举报