poj 1830

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

秩为r 自由元的个数为n-r,那么解的个数就是 1<<(n-r)

打个比方,若一开始为1,最后为0,显然这个开关应该被按,一开始为0,最后也为0,那么这个开关就不能被按。可见是否按这个开关,结果应该是stai⨁endistai⨁endi的值。
https://blog.csdn.net/acmhonor/article/details/47259481
太菜了:
https://blog.csdn.net/liverpippta/article/details/7730462

#include <iostream>// 用G++,还有就是不能外挂
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
//#define IO  ios::sync_with_stdio(false),cin.tie(0), cout.tie(0);
//#pragma comment(linker, "/STACK:1024000000,1024000000")
void ex_gcd(int a, int b, int &d, int &x, int &y) { if (!b) { x = 1; y = 0; d = a; } else { ex_gcd(b, a%b, d, y, x); y -= x * (a / b); }; }
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;}//先除后乘防溢出
int inv_exgcd(int a, int m) { int d, x, y;ex_gcd(a, m, d, x, y);return d == 1 ? (x + m) % m : -1; }
typedef long long ll;
const int maxn=1e3;
using namespace std;
int a[maxn][maxn];
int x[maxn];
map<string,int>Mon;
bool free_x[maxn];//记录不确定的变元
int eq,va;
int s[maxn],e[maxn];
int Gauss(int equ,int var)
{
    int max_r,col,k;
    int ta,tb;
    int Lcm;
    int temp;
    int free_x_num=0,free_index;
    for(int i=0;i<=var;++i) x[i]=0,free_x[i]=true;
    //转化为阶梯例
    col=0;//当前列
    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;++i) swap(a[k][i],a[max_r][i]);///i=0;
        if(!a[k][col])
        {
            k--;
            continue;//处理下一列
        }
      for(int i=k+1;i<equ;++i)
      {//化为阶梯型
          if(a[i][col])
          {
              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;++j)
              {
                  a[i][j]=((a[i][j]*ta-a[k][j]*tb)%7+7)%7;
              }
          }
      }
    }
    for(int i=k;i<equ;++i)// 无解
        if(a[i][col]) return -1;
    if(k<var)// 无穷解
    {///这这儿可以直接 return var-k;不用求出未知元
//        for(int i=k-1;i>=0;--i)
//        {
//            free_x_num=0;//用于判断不确定性变元的数量,若超过一个仍然无法求解(无解)
//            for(int j=0;j<var;++j)
//                if(a[i][j]&&free_x[j])free_x_num++,free_index=j;
//            if(free_x_num>1)continue;
//            temp=a[i][var];
//            for(int j=0;j<var;++j)
//            {
//                if(a[i][j]&&j!=free_x_num)temp=((temp-a[i][j]*x[j])%7+7)%7;;
//            }
//            x[free_index]=(temp/a[i][free_index])%7;
//            free_x[free_index]=false;
//        }
        return var-k;
    }
    //唯一解
//    for(int i=var-1;i>=0;--i)
//    {
//        temp=a[i][var]%7;
//        for(int j=i+1;j<var;++j)
//            if(a[i][j])temp=((temp-a[i][j]*x[j])%7+7)%7;//cout<<temp<<endl;
//         // if(temp%a[i][i])return -2;//有浮点数解, 说明下一行的temp/a[i][i]不是整数,也是有道理的
//         // x[i]=(temp/a[i][i])%7;
//        int d=inv_exgcd(a[i][i],7); if(d==-1)return -2; ///当逆元=-1是也是无整数解(求逆元又必须是互质的情况下)
//        x[i]=temp*d%7;
//        if(x[i]<3)x[i]+=7;
//        if(x[i]>9)x[i]%=7;
//    }
    return 0;
}
void init()
{
    int n;
    memset(a,0,sizeof(a));
    scanf("%d",&n);
    eq=va=n;
    for(int i=0;i<n;++i) scanf("%d",&s[i]);
    for(int i=0;i<n;++i) scanf("%d",&e[i]);
     memset(a,0,sizeof(a));
    for(int i=0;i<n;++i) a[i][n]=s[i]^e[i];
    for(int i=0;i<n;++i) a[i][i]=1;
    int op,po;
    while(scanf("%d%d",&op,&po),op||po)
        a[po-1][op-1]=1;
}
int main()
{//IO;
    int t;
    cin>>t;
    while(t--)
    {
        init();
        int free_num=Gauss(eq,va);
        if(free_num==-1)printf("Oh,it's impossible~!!\n");
        else
            printf("%d\n",(1<<free_num));
    }
}

猜你喜欢

转载自blog.csdn.net/sxy201658506207/article/details/83588499