关于Hilbert矩阵的几道编程题

最后一个敲了好久,写篇日志纪念一下,有需要的自取吧。

2.以浮点数的形式打印 n 阶 Hilbert 矩阵

//editor: Jan Tang
//problem: 2
#include <iostream>
#include <cstdio>
using namespace std;
#define set0(a) memset(a,0,sizeof(a));
#define CIN(a,n) for(int i=1;i<=n;i++) cin>>a[i];
typedef long long ll;
typedef unsigned long long ull;
const int Mod = 1e9+7;
const int maxn = 100005;
const int inf = 0x3f3f3f3f;
int m,n;
/*==============================head==========================*/
int main(){
    while(scanf("%d",&n)!=EOF){
        for(int i = 1; i <= n; i++){
            putchar(‘[‘);
            for(int j = 1; j <= n; j++){
                printf("%.3lf", 1.0/(i+j-1));
                if(j!=n) printf("\t ");
            }
            putchar(‘]‘);
            printf("\n");
            if(i==n) continue;

            putchar(‘[‘);
            for(int j = 1; j <= n-1; j++){
                putchar(‘\t‘);
            }
            printf("      ");
            putchar(‘]‘);
            printf("\n");
        }
    }
    return 0;
}

4.以有理数的形式打印 n 阶 Hilbert 矩阵

输出格式挺难控制的,用-左对齐

//editor: Jan Tang
//problem: 4
#include <iostream>
#include <cstdio>
using namespace std;
#define set0(a) memset(a,0,sizeof(a));
#define CIN(a,n) for(int i=1;i<=n;i++) cin>>a[i];
typedef long long ll;
typedef unsigned long long ull;
const int Mod = 1e9+7;
const int maxn = 100005;
const int inf = 0x3f3f3f3f;
int m,n;
/*==============================head==========================*/
int main(){
    while(scanf("%d",&n)!=EOF){
        for(int i = 1; i <= n; i++){
            putchar(‘[‘);
            for(int j = 1; j <= n; j++){
                printf("1/%-2d", j+i-1);
                if(j!=n) printf("\t ");
            }
            putchar(‘]‘);
            printf("\n");
            if(i==n) continue;

            putchar(‘[‘);
            for(int j = 1; j <= n-1; j++){
                putchar(‘\t‘);
            }
            printf("     ");
            putchar(‘]‘);
            printf("\n");
        }
    }
    return 0;
}

8&9.求n阶 Hilbert 矩阵的逆矩阵,并用有理数的形式打印
要用高斯消元,结合分数类来做,输出格式不想管了,放弃治疗了。

//editor: Jan Tang
//problem: 8 & 9
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <cstdlib>
using namespace std;
#define set0(a) memset(a,0,sizeof(a));
#define CIN(a,n) for(int i=1;i<=n;i++) cin>>a[i];
typedef long long ll;
typedef unsigned long long ull;
const int Mod = 1e9+7;
const int maxn = 1005;
const int inf = 0x3f3f3f3f;
int m,n;
ll gcd(ll s, ll t){
    return t==0 ? s : gcd(t, s%t);
}

struct fraction{ //分数类
    long long num, den;  //分子 numerator, 分母 denominator
    fraction(long long num = 0, long long den = 1){ //构造函数,默认值为0/1
        if(den < 0){                                //保持分母为正
            num = -num;
            den = -den;
        }
//        assert(den != 0);                            //断言:如果不满足,程序直接停止
        long long g =gcd(abs(num), den);
        this->num = num / g;
        this->den = den / g;
    }
    fraction operator +(const fraction &o) const{
        return fraction(num * o.den + den * o.num, den * o.den);
    }
    fraction operator -(const fraction &o) const{
        return fraction(num * o.den - den * o.num, den * o.den);
    }
    fraction operator *(const fraction &o) const{
        return fraction(num * o.num, den * o.den);
    }
    fraction operator /(const fraction &o) const{
        return fraction(num * o.den, den * o.num);
    }
    bool operator <(const fraction &o) const{
        return num * o.den < den * o.num;
    }
    bool operator ==(const fraction &o) const{
        return num * o.den == den * o.num;
    }
};                                    //不能漏了分号

vector<fraction> aa[maxn], bb[maxn];

inline vector<fraction> operator * (vector<fraction> a, fraction b){
    int n = a.size();
    vector<fraction> res;
    for(int i = 0; i < n ;i++){
        res.push_back(b*a[i]);
    }
    return res;
}

inline vector<fraction> operator - (vector<fraction> a, vector<fraction> b){
    int n = a.size();
    vector<fraction> res;
    for(int i = 0; i < n ;i++){
        res.push_back(a[i]-b[i]);
    }
    return res;
}

inline void inverse(vector<fraction> A[], vector<fraction> C[], int n){
    for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++){
            if(j == i) C[i].push_back(fraction(1,1));
            else C[i].push_back(fraction(0,1));
        }
    }
    for(int i = 0; i < n; i++){
        for(int j = i; j < n; j++){
            if(A[j][i].num != 0){
                swap(A[i], A[j]);
                swap(C[i], C[j]);
                break;
            }
        }
        C[i] = C[i] * (fraction(1,1) / A[i][i]);
        A[i] = A[i] * (fraction(1,1) / A[i][i]);
        for(int j = 0; j < n; j++)
            if(j != i && A[j][i].num != 0){
                C[j] = C[j] - C[i] * A[j][i];
                A[j] = A[j] - A[i] * A[j][i];
            }
    }
}
/*==============================head==========================*/
int main(){
    while(scanf("%d",&n)!=EOF){
        for(int i = 0; i < n; i++){
            aa[i].clear();
            bb[i].clear();
        }
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                aa[i].push_back(fraction(1, i+j+1));
//                printf("%lld/%lld\t", aa[i][j].num, aa[i][j].den);
            }
//            cout<<endl;
        }
    //    fraction tmp1 = fraction(2,2), tmp2 = fraction(2,4);
    //    swap(tmp1, tmp2);
    //    printf("%lld/%lld\t", tmp1.num, tmp1.den);

        inverse(aa, bb, n); //这里不用加方括号

        for(int i = 0; i < n; i++){
            putchar(‘[‘);
            for(int j = 0; j < n; j++){
                printf("%lld/%lld\t", bb[i][j].num, bb[i][j].den);
            }
            putchar(‘]‘);
            printf("\n");
            if(i==n-1) continue;

            putchar(‘[‘);
            for(int j = 1; j <= n-1; j++){
                putchar(‘\t‘);
            }
            printf("        ");
            putchar(‘]‘);
            printf("\n");
        }
    }
    return 0;
}
时间: 2024-08-28 09:45:50

关于Hilbert矩阵的几道编程题的相关文章

java基础50道编程题

50道JAVA基础编程练习题 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子对数为多少? 程序分析: 兔子的规律为数列1,1,2,3,5,8,13,21.... public class Prog1{ public static void main(String[] args){ int n = 10; System.out.println("第"+n+"个月兔子总数为&qu

每天10道编程题-第一天

[程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? [程序2]   题目:判断101-200之间有多少个素数,并输出所有素数. [程序3]   题目:打印出所有的 "水仙花数 ",所谓 "水仙花数 "是指一个三位数,其各位数字立方和等于该数本身.例如:153是一个 "水仙花数 ",因为153=1的三次方+5的三次方+3的三次方. [程

每天10道编程题-第三天

[程序21]   题目:求1+2!+3!+...+20!的和 [程序22]   题目:利用递归方法求5!.  [程序23]   题目:有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁.问第4个人岁数,他说比第3个人大2岁.问第三个人,又说比第2人大两岁.问第2个人,说比第一个人大两岁.最后问第一个人,他说是10岁.请问第五个人多大? [程序24]   题目:给一个不多于5位的正整数,要求:一.求它是几位数,二.逆序打印出各位数字. [程序25]   题目:一个5位数,判断它是不是回文数.

每天10道编程题-第四天

[程序31]   题目:将一个数组逆序输出. 1 package com.daliu.suanfa4; 2 3 public class Exp31 { 4 5 /** 6 * [程序31] 题目:将一个数组逆序输出. 7 */ 8 public static void main(String[] args) { 9 int myarr[]={1,6,9,8,5,3,7,6}; 10 for(int k=myarr.length-1;k>=0;k--) 11 System.out.print(m

网易 2016 实习研发工程师 3道 编程题-2

有一棵二叉树,树上每个点标有权值,权值各不相同,请设计一个算法算出权值最大的叶节点到权值最小的叶节点的距离.二叉树每条边的距离为1,一个节点经过多少条边到达另一个节点为这两个节点之间的距离. 给定二叉树的根节点root,请返回所求距离. //import java.util.ArrayList;   //import java.util.HashMap;   //import java.util.Iterator;   //import java.util.LinkedList;   //imp

网易 2016 实习研发工程师 3道 编程题-1

小明陪小红去看钻石,他们从一堆钻石中随机抽取两颗并比较她们的重量.这些钻石的重量各不相同.在他们们比较了一段时间后,它们看中了两颗钻石g1和g2.现在请你根据之前比较的信息判断这两颗钻石的哪颗更重. 给定两颗钻石的编号g1,g2,编号从1开始,同时给定关系数组vector,其中元素为一些二元组,第一个元素为一次比较中较重的钻石的编号,第二个元素为较轻的钻石的编号.最后给定之前的比较次数n.请返回这两颗钻石的关系,若g1更重返回1,g2更重返回-1,无法判断返回0.输入数据保证合法,不会有矛盾情况

2017-08-23 华为笔试第二道编程题详解

[题目描述] 给定一个整数,给出消除重复数字以后最大的整数 输入描述 :正整数,注意考虑长整数 输出描述 : 消除重复数字后的最大整数 [示例1] 输入 : 423234 输出 : 432 [思路] 使用栈作为辅助工具,首先从前往后遍历数组 * 栈为空就压入栈 * 栈非空,判断当前数组元素是否大于栈顶元素 * 是 , 判断栈顶元素是否在后面的数组中存在,如果存在就弹出栈顶元素 * 判断栈中是否已经存在当前数组元素,否,将当前数组元素压入栈 [参考] http://www.cnblogs.com/

每天10道编程题-第二天

[程序11]   题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?   [程序12]  题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提成7.5%:20万到40万之间时,高于20万元的部分,可提成5%:40万到60万之间时高于40万元的部分,可提成3%:60万到100万之间时,高于60万元的部分,可提成1.5%,高于100万元时,超过10

网易 2016 实习研发project师 3道 编程题

1 比較重量 给定两颗钻石的编号g1,g2,编号从1開始.同一时候给定关系数组vector,当中元素为一些二元组.第一个元素为一次比較中较重的钻石的编号,第二个元素为较轻的钻石的编号.最后给定之前的比較次数n. 请返回这两颗钻石的关系,若g1更重返回1,g2更重返回-1,无法推断返回0. 输入数据保证合法,不会有矛盾情况出现. 測试例子: 2,3,[[1,2],[2,4],[1,3],[4,3]],4 返回: 1 class Cmp { public: int cmp(int g1, int g