poj1830 开关问题 【Gauss消元】

本文介绍了一种解决开关状态变化问题的算法,通过构建开关之间的关系矩阵并运用矩阵运算,结合高斯消元法,计算出达到特定开关状态的可能方案数量。此方法适用于竞赛编程中的相关问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://poj.org/problem?id=1830

题目大意:有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开。你的目标是经过若干次开关操作后使得最后N个开关达到一个特定的状态。对于任意一个开关,最多只能进行一次开关操作。你的任务是,计算有多少种可以达到指定状态的方法。(不计开关操作的顺序)

  将方程组做成矩阵形式,然后利用三种初等矩阵变换,得到上三角矩阵,最后回代得到解集。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 41;
struct Matrix {
    int n , m;
    ll a[N][N];
    Matrix() {}
    Matrix(int _n,int _m):n(_n),m(_m){};
    void intput() {
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            scanf("%d",&a[i][j]);
    }
    void clear() {
        memset(a,0,sizeof(a));
    }
    Matrix operator + (const Matrix &b) {
        Matrix tmp = Matrix(n,m);
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            tmp.a[i][j] = a[i][j] + b.a[i][j];
        return tmp;
    }
    Matrix operator - (const Matrix &b) {
        Matrix tmp = Matrix(n,m);
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            tmp.a[i][j] = a[i][j] - b.a[i][j];
        return tmp;
    }
    Matrix operator * (const Matrix &b) {
        Matrix tmp = Matrix(n,b.m);
        for(int i=0;i<n;i++)
        for(int j=0;j<b.m;j++)
            tmp.a[i][j] = 0;
        for(int i=0;i<n;i++)
        for(int k=0;k<m;k++)
        if(a[i][k])
        for(int j=0;j<b.m;j++)
            tmp.a[i][j] += a[i][k]*b.a[k][j];
        return tmp;
    }
};

Matrix operator ^ (Matrix a , int p) {
    Matrix ret = Matrix(a.n,a.m);
    for(int i=0;i<a.n;i++)
    for(int j=0;j<a.m;j++)
        ret.a[i][j] = (i == j ? 1 : 0);
    while(p) {
        if(p%2) ret = ret * a;
        a = a * a;
        p /= 2;
    }
    return ret;
}
/*
Matrix mi(Matrix a , int p) {
    Matrix tmp = Matrix(a.n,a.m);
    for(int i=0;i<a.n;i++)
    for(int j=0;j<a.m;j++)
        if(i==j) tmp.a[i][j]=1;
        else tmp.a[i][j]=0;
    if(p == 0) return tmp;
    if(p == 1) return a;
    if(p % 2) tmp = a;
    Matrix tt = mi(a , p/2);
    return tt * tt * tmp;
}*/
Matrix A;
int Gauss(Matrix A,int r,int c) {
    int i,j,k,col;
    for(k=col=0;k<r&&col<c;k++,col++) {
        int kk = k;
        for(i=k+1;i<r;i++)
            if(A.a[i][col]>A.a[kk][col])
                kk = i;
        if(kk != k)
            for(j=col;j<c+1;j++)
                swap(A.a[k][j],A.a[kk][j]);
        if(A.a[k][col] == 0) {
            k --; continue;
        }
        for(i=k+1;i<r;i++)
            if(A.a[i][col])
                for(j=col;j<c+1;j++)
                    A.a[i][j] ^= A.a[k][j];
    }
    for(i=k;i<r;i++)
        if(A.a[i][col])
            return -1;
    int ans = 1;
    for(i=0;i<c-k;i++) ans *= 2;
    return ans;
}
int main() {
    int T , n;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        A = Matrix(n+1,n+1);
        A.clear();
        for(int i=0;i<n;i++) scanf("%d",&A.a[i][n]);
        for(int i=0;i<n;i++) {
            int tmp;
            scanf("%d",&tmp);
            A.a[i][n] ^= tmp;
        }
        int x , y;
        while(scanf("%d%d",&x,&y) && x+y) {
            x --; y --;
            A.a[y][x] = 1;
        }
        for(int i=0;i<n;i++) A.a[i][i] = 1;
        int ans = Gauss(A,n,n);
        if(ans == -1) puts("Oh,it's impossible~!!");
        else printf("%d\n" , ans);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/aiiYuu/archive/2013/04/11/3014159.html

电力系统潮流计算是电力工程领域的一项核心技术,主要用于分析电力网络在稳态运行条件下的电压、电流、功率分布等运行状态。MATLAB凭借其强大的数值计算功能和便捷的编程环境,成为电力系统潮流计算的重要工具,它提供了丰富的数学函数库,能够高效地处理复杂的电力系统计算任务。 本压缩包中的“潮流计算MATLAB程序”是一套完整的电力系统潮流计算解决方案,主要包括以下几个关键部分: 数据输入模块:该模块负责读取电力系统的网络数据,包括发电机、线路、变压器等设备的参数。这些数据通常来源于IEEE测试系统或实际电网,并以特定格式存储。 网络建模:基于输入数据,程序构建电力系统的数学模型,主要涉及节点功率平衡方程的建立。每个节点的注入功率等于其耗功率,对于发电机节点还需考虑其有功和无功功率的调节能力。 迭代算法:潮流计算的核心是求解非线性方程组,常见的算法有牛顿-拉夫森法和高斯-塞德尔法。MATLAB的优化工具箱可辅助实现这些算法,通过迭代更新节点电压和支路电流,直至满足收敛条件。 结果输出:计算完成后,程序能够输出关键性能指标,如节点电压幅值和相角、支路功率流、发电机的有功无功功率等。这些信息对于分析电网运行状态和制定调度策略具有重要意义。 可视化功能:程序可能包含图形用户界面(GUI),用于展示计算结果,例如绘制网络拓扑图并标注节点电压和支路功率,便于用户直观理解计算结果。 错误处理与调试:良好的程序设计应包含错误检测和处理机制,以应对不合理数据或计算过程中出现的问题,并给出适当的提示。 对于电力系统分析课程的学生来说,这个MATLAB程序是一个宝贵的学习资源。它不仅有助于学生掌握电力系统的理论知识,还能让他们了解如何将理论应用于实践,通过MATLAB解决实际问题。尽管该程序是作者一周内完成的,可能存在一些未完善之处,但使用者可以在参考的基础上逐步改进和完善,使其更贴合自身需求。 总之
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值