高斯消元题集

高斯消元题集

高斯消元本质上不过是线性代数中对矩阵进行的初等变换而已,结题的关键是如何构造出增广矩阵,再看方程的类型,比如整数解、浮点数解、模线性方程、或者求自由变元的数目等等再分别用不同的方式解决即可。


        关于高斯消元的原理,可以参考我的另一篇博客:高斯消元原理


HDU: 3976 4818

POJ: 1222 1830 2065 2947 3185


HDU 3976 

Electric resistance

#include <bits/stdc++.h>

using namespace std;
const int MAXN = 284;
const double eps = 1e-9;

double a[MAXN][MAXN];
double x[MAXN];
int free_x[MAXN];

int Gauss(int equ, int var) {
  int col, max_r;
  for(int k = 0, col = 0; k < equ && col < var; ++k, ++col) {
    max_r = k;
    for(int i = k + 1; i < equ; ++i) {
      if(fabs(a[i][col]) > fabs(a[max_r][col])) max_r = i;
    }
    if(fabs(a[max_r][col]) < eps) return 0; // No solution
    if(max_r != k) {
      for(int j = col; j < var; ++j) {
        swap(a[k][j], a[max_r][j]);
      }
      swap(x[k], x[max_r]);
    }
    x[k] /= a[k][col];
    for(int j = col + 1; j < var; ++j) a[k][j] /= a[k][col];
    a[k][col] = 1;
    for(int i = 0; i < equ; ++i) {
      if(i != k) {
        x[i] -= x[k] * a[i][col];
        for(int j = col + 1; j < var; ++j) a[i][j] -= a[k][j] * a[i][col];
        a[i][col] = 0;
      }
    }
  }
  return 1;
}

int main() {
  int T, cas = 1;
  scanf("%d", &T);
  while(T--) {
    int n, m;
    scanf("%d %d", &n, &m);
    int u, v, w;
    memset(a, 0, sizeof(a));
    while(m--) {
      scanf("%d %d %d", &u, &v, &w);
      a[u-1][v-1] += 1.0 / w;
      a[u-1][u-1] += -1.0 / w;
      a[v-1][u-1] += 1.0 / w;
      a[v-1][v-1] += -1.0 / w;  
    }
    for(int i = 0; i < n; ++i) x[i] = 0;
    x[0] = 1;
    for(int i = 0; i < n; ++i) {
      a[n-1][i] = 0;
    }
    a[n-1][0] = 1;
    Gauss(n, n);
    printf("Case #%d: %.2f\n", cas++, x[n-1]);
  }
  return 0;
}



HDU 4818

RP problem

#include <bits/stdc++.h>

using namespace std;
const int MAXN = 284;
const double eps = 1e-6;

double a[MAXN][MAXN], x[MAXN];
int equ, var;

int Gauss() {
  int col, max_r;
  for(int k = 0, col = 0; k < equ && col < var; ++k, ++col) {
    max_r = k;
    for(int i = k + 1; i < equ; ++i) {
      if(fabs(a[i][col]) > fabs(a[max_r][col])) {
        max_r = i;
      }
    }
    if(fabs(a[max_r][col]) < eps) return 0; // No solution
    if(max_r != k) {
      for(int j = col; j < var; ++j) {
        swap(a[k][j], a[max_r][j]);
      }
      swap(x[k], x[max_r]);
    }
    x[k] /= a[k][col];
    for(int j = col + 1; j < var; ++j) a[k][j] /= a[k][col];
    a[k][col] = 1;
    for(int i = 0; i < equ; ++i) {
      if(i != k) {
        x[i] -= x[k] * a[i][col];
        for(int j = col + 1; j < var; ++j) a[i][j] -= a[k][j] * a[i][col];
        a[i][col] = 0;
      }
    }
  }
  return 1;
}

vector<int> linker[MAXN];
int g[MAXN][MAXN], deg[MAXN], add[MAXN];
inline void init(int n) {
  for(int i = 0 ; i < n; ++i) {
    linker[i].clear();
    deg[i] = x[i] = 0;
  }
  memset(g, 0, sizeof(g));
  memset(a, 0, sizeof(a));
}

int main() {
  int T;
  scanf("%d", &T);
  while(T--) {
    int n, m;
    scanf("%d %d", &n, &m);
    equ = var = n;
    init(n);
    int u, v;
    while(m--) {
      scanf("%d %d", &u, &v);
      if(u == v) continue;
      g[u][v] = 1;
    }
    for(int i = 0; i < n; ++i) {
      for(int j = 0; j < n; ++j) {
        if(j != i && g[i][j]) {
          deg[i]++;
          linker[j].push_back(i);
        }
      } 
    }
    for(int i = 0; i < n; ++i) {
      a[i][i] = -1;
      for(int j = 0; j < linker[i].size(); ++j) {
        int v = linker[i][j];
        if(i == v) continue;
        a[i][v] = 1.0 / deg[v];
      }
    }
    for(int i = 0; i < n; ++i) {
      a[n-1][i] = 1;
    }
    x[n-1] = 1;

    for(int k = 0; k < n-1; ++k) {
      if(g[n-1][k] == 0) {
        for(int i = 0; i < n-1; ++i) {
          if(g[n-1][i]) a[i][var] = 1.0 / (deg[n-1] + 1);
          else a[i][var] = 0;
        }                                               
        a[k][var] = 1.0 / (deg[n-1] + 1);              
        a[n-1][var] = 1;
        add[var] = k;
        var++;
      }
    }
    if(!Gauss()) {
      puts("INF");
      continue;
    }
    double now = x[n-1];
    int ans  = -1;
    for(int i = n; i < var; ++i) {
      if(x[n-1] / a[n-1][i] > now) {
        ans = add[i];
        now = x[n-1] / a[n-1][i];
      }
    }
    printf("1 %d\n", ans);
  }
  return 0;
}


POJ 1222

EXTENDED LIGHTS OUT

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;
const int MAXN = 128;

int a[MAXN][MAXN];
int x[MAXN];
bool free_x[MAXN];

int gcd(int a, int b) {
  return b == 0 ? a : gcd(b, a % b);
}

int lcm(int a, int b) {
  return a / gcd(a, b) * b;
}

int Gauss(int equ, int var) {
  for(int i = 0; i <= var; ++i) {
    x[i] = 0;
    free_x[i] = true;
  }
  int max_r;
  for(int col = 0, row = 0; col < var && row < equ; ++col, ++row) {
    max_r = row;
    for(int i = row + 1; i < equ; ++i) {
      if(abs(a[max_r][col]) < abs(a[i][col])) {
        max_r = i;
      }
    }
    if(max_r != row) {
      for(int j = row; j < var + 1; ++j) {
        swap(a[row][j], a[max_r][j]);
      }
    }
    if(a[row][col] == 0) {
      row--;
      continue;
    }
    for(int i = row + 1; i < equ; ++i) {
      if(a[i][col] != 0) {
        for(int j = col; j < var + 1; ++j) {
          a[i][j] ^= a[row][j];
        }
      }
    }
  }
  for(int i = var - 1; i >= 0; --i) {
    x[i] = a[i][var];
    for(int j = i + 1; j < var; ++j) {
      x[i] ^= (a[i][j] & x[j]);
    }
  }
  return 0;
}

int main() {
  int T, cas = 1;
  scanf("%d", &T);
  while(T--) {
    memset(a, 0, sizeof(a));
    for(int i = 0; i < 30; ++i) {
      scanf("%d", &a[i][30]);
    }  
    for(int i = 0; i < 5; ++i) {
      for(int j = 0; j < 6; ++j) {
        int t = i * 6 + j;
        a[t][t] = 1;
        if(i > 0) a[(i - 1) * 6 + j][t] = 1;
        if(i < 4) a[(i + 1) * 6 + j][t] = 1;
        if(j > 0) a[i * 6 + j - 1][t] = 1;
        if(j < 5) a[i * 6 + j + 1][t] = 1;
      }
    }
    Gauss(30, 30);
    printf("PUZZLE #%d\n", cas++);
    for(int i = 0; i < 30; ++i) {
      printf("%d", x[i]);
      if((i + 1) % 6 == 0) printf("\n");
      else printf(" ");
    }
  }
  return 0;
}


POJ  1830 

开关问题

 


#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int MAXN = 284;
const double eps = 1e-6;

int a[MAXN][MAXN];
int x[MAXN];
int free_x[MAXN];

int Gauss(int equ, int var) {
  int k, max_r, col, ta, tb;
  for(int i = 0; i <= var; ++i) {
    x[i] = 0;
    free_x[i] = 1;
  }
  for(k = 0, col = 0; k < equ && col < var; ++k, ++col) {
    max_r = k;
    for(int i = k + 1; i < equ; ++i) {
      if(abs(a[i][col]) > abs(a[max_r][col])) max_r = i;
    }
    if(max_r != k) {
      for(int i = k; i < var + 1; ++i) swap(a[max_r][i], a[k][i]);
    }
    if(a[k][col] == 0) {
      k--;
      continue;
    }
    for(int i = k + 1; i < equ; ++i) {
      if(a[i][col] != 0) {
        for(int j = col; j < var + 1; ++j) {
          a[i][j] ^= a[k][j];
        }
      }
    }
  }
  for(int i = k; i < equ; ++i) {
    if(a[i][col] != 0) return -1;
  }
  return var - k;
}

int st[MAXN], en[MAXN];

int main() {
  int T;
  scanf("%d", &T);
  while(T--) {
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i) scanf("%d", st + i);
    for(int i = 0; i < n; ++i) scanf("%d", en + i);
    memset(a, 0, sizeof(a));
    int u, v;
    while(scanf("%d %d", &u, &v), u || v) {
      a[v-1][u-1] = 1;
    }
    for(int i = 0; i < n; ++i) a[i][i] = 1;
    for(int i = 0; i < n; ++i) a[i][n] = st[i] ^ en[i];
    int ans = Gauss(n, n);
    if(ans == -1) {
      puts("Oh,it's impossible~!!");
    } else {
      printf("%d\n", 1 << ans);
    }
  }
  return 0;
}


POJ 2065 

SETI

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>

using namespace std;
const int MAXN = 108;
const int inf = 0x7fffffff;
int n, mod;

int a[MAXN][MAXN];
int x[MAXN];
bool free_x[MAXN];

char str[MAXN];

int quickPow(int a, int p, int mod) {
  int ans = 1;
  a %= mod;
  while(p) {
    if(p & 1) {
      ans = (ans * a % mod) % mod;
    }
    a = a * a % mod;
    p >>= 1;
  }
  return ans;
}

int gcd(int a, int b) {
  return b == 0 ? a : gcd(b, a % b);
}

int lcm(int a, int b) {
  return a / gcd(a, b) * b;
}

int Gauss(int equ, int var, int mod) {
  int k, max_r;
  int col;
  int ta, tb;
  int LCM;
  int tmp;
  int free_x_num;
  int free_index;

  for(int i = 0; i <= var; ++i) {
    x[i] = 0;
    free_x[i] = true;
  }
  col = 0;
  for(k = 0; k < equ && col < var; ++k, ++col) {
    max_r = k;
    for(int i = k + 1; i < equ; ++i) {
      if(abs(a[i][col]) < abs(a[max_r][col])) max_r = i;
    }
    if(max_r != k) {
      for(int j = k; j < var + 1; ++j) swap(a[k][j], a[max_r][j]);
    }
    if(a[k][col] == 0) {
      k--;
      continue;
    }
    for(int i = k + 1; i < equ; ++i) {
      if(a[i][col] != 0) {
        LCM = lcm(abs(a[i][col]), abs(a[k][col]));
        ta = LCM / abs(a[i][col]);
        tb = LCM / abs(a[k][col]);
        if(a[i][col] * a[k][col] < 0) tb = -tb;
        for(int j = col; j < var + 1; ++j) {
          a[i][j] = ((a[i][j] * ta - a[k][j] * tb) % mod + mod) % mod; 
        }
      }
    }
  }
  for(int i = var - 1; i >= 0; --i) {
    tmp = a[i][var];
    for(int j = i + 1; j < var; ++j) {
      if(a[i][j] != 0) tmp -= a[i][j] * x[j];
      tmp = (tmp % mod + mod) % mod;
    }
    while(tmp % a[i][i] != 0) tmp += mod;
    x[i] = (tmp / a[i][i]) % mod;
  }
  return 0;
}


int main() {
  int T;
  scanf("%d", &T);
  while(T--) {
    memset(a, 0, sizeof(a));
    scanf("%d %s", &mod, &str);
    n = strlen(str);
    for(int i = 0; i < n; ++i) {
      if(str[i] != '*') {
        a[i][n] = str[i] - 'a' + 1;
      } else {
        a[i][n] = 0;
      }
      for(int j = 0; j < n; ++j) {
        a[i][j] = quickPow(i + 1, j, mod);
      }
    }
    Gauss(n, n, mod);
    for(int i = 0; i < n; ++i) {
      if(i == n - 1) printf("%d\n", x[i]);
      else printf("%d ", x[i]);
    }
  }
  return 0;
}

POJ 2947 

Widget Factory

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>

using namespace std;
const int MAXN = 328;
const int mod = 7;
const int inf = 0x7fffffff;

int a[MAXN][MAXN];
int x[MAXN];
bool free_x[MAXN];

map<string, int> mp;

int gcd(int a, int b) {
  return b == 0 ? a : gcd(b, a % b);
}

int lcm(int a, int b) {
  return a / gcd(a, b) * b;
}

int Gauss(int equ, int var, int mod) {
  int i, j, k;
  int max_r, col;
  int ta, tb;
  int LCM, tmp;
  int free_x_num;
  int free_index;
  for(int i = 0; i <= var; ++i) {
    x[i] = 0;
    free_x[i] = true;
  }
  col = 0;
  for(k = 0; k < equ && col < var; k++, col++) {
    max_r = k;
    for(i = k + 1; i < equ; ++i) {
      if(abs(a[i][col]) > abs(a[max_r][col])) max_r = i;
    }
    if(max_r != k) {
      for(j = k; j < var + 1; ++j) swap(a[k][j], a[max_r][j]);
    }
    if(a[k][col] == 0) {
      k--;
      continue;
    }
    for(i = k + 1; i < equ; ++i) {
      if(a[i][col] != 0) {
        LCM = lcm(abs(a[i][col]), abs(a[k][col]));
        ta = LCM / abs(a[i][col]);
        tb = LCM / abs(a[k][col]);
        if(a[i][col] * a[k][col] < 0) tb = -tb;
        for(j = col; j < var + 1; ++j) {
          a[i][j] = ((a[i][j] * ta - a[k][j] * tb) % mod + mod) % mod;
        }
      }
    }
  }
  
  for(i = k; i < equ; ++i) {
    if(a[i][col] != 0) return -1;  // No Solution
  }
  if(k < var) return var - k;      // Infinity solutions
  for(int i = var - 1; i >= 0; --i) {
    tmp = a[i][var];
    for(int j = i + 1; j < var; ++j) {
      if(a[i][j] != 0) tmp -= a[i][j] * x[j];
      tmp = (tmp % mod + mod) % mod;
    }
    while(tmp % a[i][i] != 0) tmp += mod;
    x[i] = (tmp / a[i][i]) % mod;
  }
  return 0;
 }

int main() {
  mp["MON"] = 1;
  mp["TUE"] = 2;
  mp["WED"] = 3;
  mp["THU"] = 4;
  mp["FRI"] = 5;
  mp["SAT"] = 6;
  mp["SUN"] = 7;
  
  int n, m;
  char d1[20], d2[20];
  while(scanf("%d %d", &n, &m), n || m) {
    memset(a, 0, sizeof(a));
    int k;
    for(int i = 0; i < m; ++i) {
      scanf("%d%s%s", &k, &d1, &d2);
      a[i][n] = mp[d2] - mp[d1] + 1;
      // cerr << a[i][n] << endl;
      int id;
      while(k--) {
        scanf("%d", &id);
        a[i][id - 1]++;
        a[i][id - 1] %= 7; 
      }
    }
    // test starts
    /*
    cerr << " n = " << n << " m = " << m << endl;
    for(int i = 0; i < m; ++i) {
      for(int j = 0; j < n + 1; ++j) {
        cerr << a[i][j] << " ";
      }
      cout << endl;
    }
    */
    // test ends
    int ans = Gauss(m, n, mod);
    // test starts
    /*
    cerr << " ans = " << ans << endl;
    for(int i = 0; i < n; ++i) {
      cerr << x[i] << " ";
    }
    */
    // test ends
    if(ans == 0) {
      for(int i = 0; i < n; ++i) {
        if(x[i] <= 2) x[i] += 7;
      }
      for(int i = 0; i < n; ++i) {
        if(i == n - 1) printf("%d\n", x[i]);
        else printf("%d ", x[i]);
      }
    }
    else if(ans == -1) {
      puts("Inconsistent data.");
    } else { 
      puts("Multiple solutions.");  
    }  
  }
  return 0;
}

POJ 3185 

The Water Bowls

 

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

using namespace std;
const int INF = 0x7fffffff;
const int MAXN = 27;

int a[MAXN][MAXN];
int x[MAXN];

//高斯消元法解模线性方程组
bool free_x[MAXN];//标记是否是不确定的变元
int gcd(int a, int b) {
  return b ? gcd(b, a % b) : a;
}

int lcm(int a, int b) {
  return a / gcd(a, b) * b;
}

// 高斯消元法解方程组
//-2表示有浮点数解,但无整数解
//-1表示无解
//0表示唯一解
//大于0表示无穷解,并返回自由变元的个数
//有equ个方程,var个变元
//增广矩阵行数为equ,分别为0到equ-1,列数为var+1,分别为0到var.
int Gauss(int equ, int var, int mod) {
  int i, j, k;
  int max_r;//当前这列绝对值最大的行.
  int col;//当前处理的列
  int ta, tb;
  int LCM;
  int temp;
  int free_x_num;
  int free_index;
  for (int i = 0; i <= var; i++) {
    x[i] = 0;
    free_x[i] = true;
  }
  //转换为阶梯阵.
  col = 0;//当前处理的列
  for (k = 0; k < equ && col < var; k++, col++) {
    // 枚举当前处理的行.
    // 找到该col列元素绝对值最大的那行与第k行交换(为了在除法时减小误差)
    max_r = k;
    for (i = k + 1; i < equ; i++) {
      if (abs(a[i][col]) > abs(a[max_r][col])) max_r = i;
    }
    if (max_r != k) {// 与第k行交换.
      for (j = k; j < var + 1; j++) swap(a[k][j], a[max_r][j]);
    }
    if (a[k][col] == 0) {// 说明该col列第k行以下全是0了,则处理当前行的下一列.
      k--;
      continue;
    }
    for (i = k + 1; i < equ; i++) {// 枚举要删去的行.
      if (a[i][col] != 0) {
        LCM = lcm(abs(a[i][col]), abs(a[k][col]));
        ta = LCM / abs(a[i][col]);
        tb = LCM / abs(a[k][col]);
        if (a[i][col] * a[k][col] < 0)tb = -tb;//异号的情况是相加
        for (j = col; j < var + 1; j++) {
          a[i][j] = ((a[i][j] * ta - a[k][j] * tb) % mod + mod) % mod;
        }
      }
    }
  }
  //无解的情况
  for (i = k; i < equ; i++) {
    if (a[i][col] != 0) return -1;
  }
  //找出和最小的解
  int ans = INF;
  for (int state = 0; state < (1 << (var - k)); state++) {
    int cnt = 0;
    for (int i = 0; i < var - k; i++)
      if (state & (1 << i))x[i + k] = 1, cnt++;
      else x[i + k] = 0;
    for (int i = k - 1; i >= 0; i--) {
      temp = a[i][var];
      for (j = i + 1; j < var; j++) {
        if (a[i][j] != 0) temp -= a[i][j] * x[j];
        temp = (temp % mod + mod) % mod;
      }
      while (temp % a[i][i] != 0) temp += mod;
      x[i] = (temp / a[i][i]) % mod;
      cnt += x[i];
    }
    ans = min(ans, cnt);
  }
  return ans;
}

int main() {
  int n = 20;
  memset(a, 0, sizeof(a));
  for (int i = 0; i < 20; ++i) {
    scanf("%d", &a[i][n]);
  }
  for (int i = 0; i < n; ++i) {
    a[i][i] = 1;
    if (i > 0) a[i - 1][i] = 1;
    if (i < n - 1) a[i + 1][i] = 1;
  }
  int ans = Gauss(n, n, 2);
  printf("%d\n", ans);
  return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值