1031: 找规律I
时间限制: 1 Sec 内存限制: 128 MB提交: 417 解决: 180
[提交][状态][讨论版]
题目描述
北雷老中医给了大面包一个n*m矩阵,解开这个矩阵(把这个矩阵的每个元素加起来的和输出来)的奥秘衣服就再也不会掉到床底了(大面包衣服什么的总是掉到床底)。
老中医给了大面包几个样本,请帮助大面包找出规律,破解奥秘。
5 6
2 3 4 5 6 7
3 2 5 3 7 4
4 5 2 7 8 3
5 3 7 2 9 5
6 7 8 9 2 11
154
3 10
2 3 4 5 6 7 8 9 10 11
3 2 5 3 7 4 9 5 11 6
4 5 2 7 8 3 10 11 4 13
187
8 8
2 3 4 5 6 7 8 9
3 2 5 3 7 4 9 5
4 5 2 7 8 3 10 11
5 3 7 2 9 5 11 3
6 7 8 9 2 11 12 13
7 4 3 5 11 2 13 7
8 9 10 11 12 13 2 15
9 5 11 3 13 7 15 2
442
输入
多组数据
每组数据包含一行,2个数N、M,N表示行数,M表示列数(1 <= N,M <= 1000)
输出
输出一行,矩阵所有元素的和
样例输入
5 6
3 10
8 8
样例输出
154
187
442
解析:求最大公约数问题
猛一看这道题一点头绪都没有,看起来矩阵行列之间并没有什么规律,网上搜了一下发现这个规律真的很难发现。
看每个矩阵的第一行不难发现,都是从2开始递增到2+M-1,以第二个输入为例观察其余行:
j: 1 2 3 4 5 6 7 8 9 10
i=2: 3 2 5 3 7 4 9 5 11 6
i+j: 4 4 5 6 7 8 9 10 11 12
i=3: 4 5 2 7 8 3 10 11 4 13
i+j: 4 5 6 7 8 9 10 11 12 13
依此类推,不难发现,当i,j没有最大公约数时,输入矩阵对应值为(i+j),有最大公约数时,输入矩阵对应值为(i+j)/i,j的最大公约数。
代码如下:
#include<iostream>
using namespace std;
//辗转相除法效率高
int gcd(int a,int b){
if(b==0)
return a;
return gcd(b,a%b);
}
int main(){
int N,M,ans;
while(scanf("%d%d",&N,&M)!=EOF){
ans=0;
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
ans+=(i+j)/gcd(i,j);
}
}
printf("%d\n",ans);
}
}
顺便说一下,输入多组数据while(scanf("%d%d",&N,&M)!=EOF),不加EOF会时间超限。