hdu5755

與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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章