问题 A: 分数矩阵
题目描述
我们定义如下矩阵:
1/1 1/2 1/3
1/2 1/1 1/2
1/3 1/2 1/1
矩阵对角线上的元素始终是1/1,对角线两边分数的分母逐个递增。
请求出这个矩阵的总和。
1/1 1/2 1/3
1/2 1/1 1/2
1/3 1/2 1/1
矩阵对角线上的元素始终是1/1,对角线两边分数的分母逐个递增。
请求出这个矩阵的总和。
输入
输入包含多组测试数据。每行给定整数N(N<50000),表示矩阵为N*N。当N=0时,输入结束。
输出
输出答案,结果保留2位小数。
样例输入
1
2
3
4
0
样例输出
1.00 3.00 5.67 8.83
这题就是一个规律题
#include<stdio.h> int main () { int n; int i; double sum; while(scanf("%d",&n),n) { sum=0; sum+=n*1; for (i=2;i<=n;i++) { sum+=1.0/i*(n-i+1)*2; } printf ("%.2f\n",sum); } return 0; }
用算法笔记上的写法时间超限了
#include<bits/stdc++.h> using namespace std; struct Fraction { int up,down;//分子 分母 //Fraction(){} Fraction(int _up=0,int _down=0):up(_up),down(_down){} }; int gcd(int a,int b) { if(b==0) return a; return gcd(b,a%b); } Fraction reduction(Fraction result)//分数的化简 { if(result.down<0){//分母为负数,令分子和分母都变为相反数 result.down=-result.down; result.up=-result.up; } if(result.up==0) result.down=1;//如果分子为0 分母为1 else{//约去最大公约数 int d=gcd(abs(result.up),abs(result.down)); result.up/=d; result.down/=d; } return result; } int main() { int n; while(scanf("%d",&n)==1&&n!=0){ Fraction s[n*n+10]; for(int i=1;i<=n;i++){ s[n*(i-1)+i].up=1; s[n*(i-1)+i].down=1; } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i!=j){ if(j>i){ s[n*(i-1)+j].down=s[n*(i-1)+j-1].down+1; s[n*(i-1)+j].up=1; } } } } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(j<i){ s[n*(i-1)+j].down=s[n*n+1-n*(i-1)-j].down; s[n*(i-1)+j].up=1; } } } Fraction c; c.down=s[1].down; c.up=s[1].up; for(int i=2;i<=n*n;i++){ c.up=s[i].up*c.down+c.up*s[i].down; c.down=s[i].down*c.down; c=reduction(c); cout<<c.up<<" "<<c.down<<endl; } printf("%.2f\n",1.0*c.up/c.down); } return 0; }
分数的四则运算就是我们正常的四则运算