决战 - 构造

给你一个n*n的矩阵的第1行,并保证第一行存在两个数字互质,构造剩下的n-1行使得行列式是1。 n ≤ 5 n\le5 n5,输入的数字和你填的数字必须是绝对值在 [ − 2000 , 2000 ] [-2000,2000] [2000,2000]的整数。
题解:
考虑n=2怎么做,exgcd即可。然后再填n-2个1即可保证有值的排列只有最多两个。

#include
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
#define debug(x) cerr<<#x<<"="<
#define sp <<" "
#define ln <
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn(int x=0) { return scanf("%d",&x),x; }
const int N=6;int h[N][N];
namespace subtask1{ inline int calc1() { return !printf(h[1][1]==1?"1\n":"no solution\n"); } }
inline int gabs(int x) { return x<0?-x:x; }
inline int gcd(int x,int y) { return x?gcd(y%x,x):y; }
inline int exgcd(int a,int b,int &x,int &y)
{
    if(!b) return x=1,y=0;
    return exgcd(b,a%b,y,x),y-=x*(a/b);
}
int main()
{
    int n=inn();rep(i,1,n) h[1][i]=inn();
    if(n==1) return subtask1::calc1();int p=0,q=0;
    rep(i,1,n) rep(j,i+1,n) if(gcd(gabs(h[1][i]),gabs(h[1][j]))==1) p=i,q=j;
    int a=h[1][p],b=-h[1][q],&x=h[2][q],&y=h[2][p];
    if(a==0) x=0,y=b;
    else if(b==0) x=a,y=0;
    else{
        exgcd(gabs(a),gabs(b),x,y);
        if(a<0) x=-x;if(b<0) y=-y;
    }
    if((p+q-3)&1) x=-x,y=-y;
    for(int i=3,j=1;i<=n;i++,j++)
    { if(j==p) j++;if(j==q) j++;h[i][j]=1; }
    rep(i,1,n) rep(j,1,n) printf("%d%c",h[i][j]," \n"[j==n]);
    return 0;
}

你可能感兴趣的:(构造)