zoukankan      html  css  js  c++  java
  • 【算法】高斯消元&线性代数

    寒假作业~就把文章和题解3道题的代码扔在这里啦——链接: https://pan.baidu.com/s/1kWkGnxd 密码: bhh9

    1.HNOI2013游走

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 600
    #define db double
    int n, m, degree[maxn];
    db f[maxn][maxn], ans[maxn], fans;
    bool dis[maxn][maxn];
    
    struct edge
    {
        int x, y;
        db ans;
    }R[maxn * maxn];
    
    int read()
    {
        int x = 0, k = 1;
        char c;
        c = getchar();
        while(c < '0' || c > '9') { if(c == '-') k = -1; c = getchar(); }
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * k;
    }
    
    bool cmp(edge a, edge b)
    {
        return a.ans > b.ans;
    }
    
    void Gauss()
    {
        for(int i = 1; i <= n; i ++)
        {
            int now = i, j = i;
            for(int j = i + 1; j <= n; j ++)
                if(fabs(f[j][i]) > fabs(f[now][i])) now = j;
            if(i != now)
            {
                for(int k = 1; k <= n + 1; k ++)
                    swap(f[i][k], f[now][k]);
            }
            for(int j = i + 1; j <= n + 1; j ++)
                f[i][j] /= f[i][i];
            for(int j = 1; j <= n; j ++)
            {
                if(j == i) continue;
                for(int k = i + 1; k <= n + 1; k ++)
                    f[j][k] -= f[j][i] * f[i][k]; 
            }
        }
    }
    
    int main()
    {
        n = read(), m = read();
        for(int i = 1; i <= m; i ++)
        {
            int x = read(), y = read();
            R[i].x = x, R[i].y = y;
            degree[x] ++, degree[y] ++, dis[x][y] = dis[y][x] = true;
        }
        n -= 1;
        for(int i = 1; i <= n; i ++)
            for(int j = 1; j <= n; j ++)
                if(dis[i][j]) f[i][j] = - (1 / (db) degree[j]);
                else if(i == j) f[i][j] = 1;
        f[1][n + 1] = 1;
        Gauss();
        for(int i = 1; i <= n; i ++) ans[i] = f[i][n + 1];
        for(int i = 1; i <= m; i ++)
            R[i].ans = ((db) ans[R[i].x] / (db) degree[R[i].x]) + ((db) ans[R[i].y] / (db) degree[R[i].y]);
        sort(R + 1, R + 1 + m, cmp);
        for(int i = 1; i <= m; i ++)
            fans += (db) i * R[i].ans;
        printf("%.3lf
    ", fans);
        return 0;
    }

    2.USACO灯

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 60
    int n, m, a[maxn][maxn], ans[maxn], fans = 999999, tot;
    
    int read()
    {
        int x = 0, k = 1;
        char c;
        c = getchar();
        while(c < '0' || c > '9') { if(c == '-') k = -1; c = getchar(); }
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * k;
    }
    
    void Gauss()
    {
        for(int i = 1; i <= n; i ++)
        {
            int now = i, j = i;
            while(j <= m && !a[j][i]) j ++;
            if(j > m) continue;
            if(now != j)
            {
                for(int k = 1; k <= n + 1; k ++)
                    swap(a[now][k], a[j][k]);
            }
            for(int j = 1; j <= n; j ++)
                if(j != i && a[j][i])
                {
                    for(int k = 1; k <= n + 1; k ++)
                        a[j][k] ^= a[i][k];
                }
        }
    }
    
    void dfs(int now)
    {
        if(tot >= fans) return;
        if(!now)
        {
            fans = min(fans, tot);
            return;
        }
        if(a[now][now]) //不是自由元 
        {
            int tem = a[now][n + 1];
            for(int i = now + 1; i <= n; i ++)
                if(a[now][i]) tem ^= ans[i];
            ans[now] = tem;
            if(tem) tot ++; 
            dfs(now - 1); 
            if(tem) tot --;
        }
        else 
        {
            ans[now] = 0;
            dfs(now - 1);
            tot ++;
            ans[now] = 1;
            dfs(now - 1);
            tot --;
        }
    }
    
    int main()
    {
        n = read(), m = read();
        for(int i = 1; i <= n; i ++)
            a[i][i] = 1, a[i][n + 1] = 1;
        for(int i = 1; i <= m; i ++)
        {
            int x = read(), y = read();
            a[x][y] = 1, a[y][x] = 1;
        }
        Gauss();
        dfs(n);
        printf("%d", fans);
    } 

    3.NOIP2004虫食算

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 40
    int n, f[maxn][maxn], g[maxn][maxn], d[maxn], x[maxn];
    char s[3][maxn];
    bool vis[maxn], flag;
    
    int GCD(int x, int y)
    {
        int z;
        while(y)
        {
            z = x % y;
            x = y, y = z;
        }
        return x;
    }
    
    int LCM(int x, int y)
    {
        return (x * y / GCD(x, y));
    } 
    
    void check()
    {
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= n; i ++)
        {
            int sum = 0;
            for(int j = 2; j <= n; j ++)
                sum += d[j] * g[i][j];
            if(sum % f[i][i]) return;
            sum /= f[i][i];
            if(sum < 0 || sum >= n || vis[sum]) return;
            vis[x[i] = sum] = true;
        }
        flag = true;
    }
    
    void solve()
    {
        for(int p = 1; p <= n; p ++)
        {
            int now = p;
            for(int i = p + 1; i <= n; i ++)
                if(abs(f[i][p]) > abs(f[now][p])) now = i;
            if(now != p)
            {
                for(int i = 1; i <= n; i ++)
                    swap(f[now][i], f[p][i]), swap(g[now][i], g[p][i]);
            } 
            for(int i = 1; i <= n; i ++)
                if(i != p && f[i][p])
                {
                    int lcm = LCM(f[i][p], f[p][p]);
                    int d1 = lcm / f[i][p], d2 = lcm / f[p][p];
                    for(int j = 1; j <= n; j ++)
                    {
                        f[i][j] = f[i][j] * d1 - f[p][j] * d2;
                        g[i][j] = g[i][j] * d1 - g[p][j] * d2;
                    }
                }
        }
    }
    
    void dfs(int u)
    {
        if(u == 1) 
        {
            check();
            if(flag)
            {
                for(int i = 1; i < n; i ++)
                    printf("%d ", x[i]);
                printf("%d
    ", x[n]);
                exit(0);
            }
            return;
        }
        d[u] = 0, dfs(u - 1);
        d[u] = 1, dfs(u - 1);
    }
    
    int main()
    {
        scanf("%d", &n);
        scanf("%s%s%s", s[0] + 1, s[1] + 1, s[2] + 1);
        for(int i = 1; i <= n; i ++)
            for(int j = 0; j <= 2; j ++)
                if(j < 2) f[i][s[j][i] - 'A' + 1] += 1;
                else f[i][s[j][i] - 'A' + 1] -= 1;
        for(int i = 1; i <= n; i ++)
            g[i][i] = n, g[i][i + 1] = -1;
        solve();
        dfs(n);
        return 0;
    } 
  • 相关阅读:
    还有更简单的不重复随机数生成方法吗?
    SqlServer数据插入性能小记
    html页面滚动时元素错位解决方案
    为Web页中的Table对象创建一个映射表
    js实现的快速排序
    webkit内核的浏览器为什么removeAttribute('style')会失效?
    setAttribute第三个参数
    Windows转到linux中,文件乱码,文件编码转换
    查看端口的占用
    sndfile
  • 原文地址:https://www.cnblogs.com/twilight-sx/p/8467871.html
Copyright © 2011-2022 走看看