hdu5755

来源:互联网 发布:知鸟二维码图片 编辑:程序博客网 时间:2024/05/22 03:33

与poj1681类似的一道题,不同的是这里使用的是除法而不是异或

#include <iostream>#include <vector>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>using namespace std;vector<int> ans;const int MAXN = 900+5;int equ, var;///equ个方程 var个变量int a[MAXN][MAXN];///增广矩阵int x[MAXN];///解的数目bool free_x[MAXN];///判断是不是自由变元int free_num;///自由变元的个数inline int GCD(int m, int n){    if(n == 0)        return m;    return GCD(n, m%n);}inline int LCM(int a, int b){    return a/GCD(a,b)*b;}int Gauss(){    int Max_r;///当前列绝对值最大的存在的行    ///col:处理当前的列    int row = 0;    int free_x_num;    int free_index = -1;    for(int col=0; row<equ&&col<var; row++,col++)    {        Max_r = row;        for(int i=row+1; i<equ; i++)            if(abs(a[i][col]) > abs(a[Max_r][col]))                Max_r = i;        if(Max_r != row)            for(int i=0; i<var+1; i++)                swap(a[row][i], a[Max_r][i]);        if(a[row][col] == 0)        {            row--;            continue;        }        for(int i=row+1; i<equ; i++)        {            if(a[i][col])            {                int lcm = LCM(abs(a[i][col]), abs(a[row][col]));                int tp1=lcm/abs(a[i][col]), tp2=lcm/abs(a[row][col]);                if(a[row][col]*a[i][col] < 0)                    tp2 = -tp2;                for(int j=col; j<var+1; j++)                {                    a[i][j] = tp1*a[i][j]-tp2*a[row][j];                    a[i][j] = (a[i][j]%3+3)%3;                }            }        }    }    /**if(row < var)    {        for(int i=row-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 || free_index==-1)                continue;            int tmp = a[i][var];            for(int j=0; j<var; j++)                if(a[i][j] && j!=free_index)                {                    tmp -= a[i][j]*x[j];                    tmp = (tmp%3+3)%3;                }            x[free_index] = (tmp*a[i][free_index]);/// 求出该变元.            x[free_index] %= 3;            free_x[free_index] = 0; /// 该变元是确定的.        }        return var - row;///自由变元的个数    }*/    for(int i=var-1; i>=0; i--)    {        int tmp = a[i][var];        for(int j=i+1; j<var; j++)            if (a[i][j])            {                tmp -= a[i][j]*x[j];                tmp = (tmp%3+3)%3;            }        x[i] = tmp*a[i][i];        x[i] %= 3;    }    return 0;///唯一解}int main(){    int T, m, n;    scanf("%d",&T);    while(T--)    {        ans.clear();        scanf("%d%d",&m,&n);        equ = var = m*n;        memset(a, 0, sizeof(a));        for(int i=0; i<var; i++)        {            int ta = i%n, tb = i/n;            a[i][i] = 2;            if(ta > 0)                a[i][i-1] = 1;            if(ta < n-1)                a[i][i+1] = 1;            if(tb > 0)                a[i][i-n] = 1;            if(tb < m-1)                a[i][i+n] = 1;        }        for(int i=0; i<m; i++)        {            for(int j=0; j<n; j++)            {                int tt;                scanf("%d",&tt);                a[i*n+j][var] = ((3-tt)%3);//需要被操作几次才能归零            }        }        int S = Gauss();        for(int i=0; i<var; i++)        {            while(x[i])            {                x[i]--;                ans.push_back(i);            }        }        printf("%d\n",ans.size());        for(int i=0; i<ans.size(); i++)        {            int ta = ans[i]%n;            int tb = ans[i]/n;            printf("%d %d\n", tb+1, ta+1);        }    }    return 0;}
0 0
原创粉丝点击