题目链接:http://codeforces.com/contest/599/problem/D
一个3×5(m×n)的长方形,里面包含15个边长为1的正方形,有8个边长为2的正方形,有3个边长为3的正方形,所以一共有 15+8+3=26 (num)个正方形,现在告诉你26(num),让你求有几个满足这样条件的长方形,并把对应的长和宽输出来;
一个m×n的长方形,里面包含正方形个数是:∑((m-a+1)*(n-a+1))(1<a<min(m, n));
我们可以枚举所有的 m 然后求出对应的整数解 n 即可,注意由于数的取值范围比较大,所以不能打表,要一次算出 n ;
当num = 26 时;
m = 1 : 1*n = 26; n = 26;
m = 2 : 2*n + 1*(n-1) = 26; n = 9;
m = 3 : 3*n + 2*(n-1) + 1*(n-2) = 26; n = 5;
m = 4 : 4*n + 3*(n-1) + 2*(n-2) + 1*(n-3) = 26; n无整数解;
m = 5 : 5*n + 4*(n-1) + 3*(n-2) + 2*(n-3) + 1*(n-4) = 26; n = 3;
...........
由上面可知,当任意m对应的式子都是
(1+2+3+...+m)n -[ (1) + (1+2) + (1+2+3) + ... + (1+2+3+...+m-2) + (1+2+3+...+m-1)] = num;
p n - q = num;
所以n = (num + q)/p;
当然在计算p和q时,用到一下公式:
1 + (1+2) + (1+2+3) +(1+2+3+4)+ ... +(1+2+3+...+n) = n*(n+1)*(n+2)/6
拓展:
1² + 2² + 3² + ... + n² = n*(n+1)*(2n+1)/6;
#include <iostream> #include <vector> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> #include <math.h> using namespace std; #define N 10000050 #define PI 4*atan(1) #define met(a, b) memset(a, b, sizeof(a)) typedef long long LL; LL num; struct node { LL m, n; }a[N]; int cmp(node p, node q) { if(p.n != q.n) return p.n < q.n; return p.m < q.m; } int main() { while(scanf("%I64d", &num)!=EOF) { int ans = 0; LL f = 0; for(LL i=1; i<=num && f<=num; i++)///结束条件就是不能让常数项大于num; { LL p = ((i+1)*i)/2;///X的系数; LL q = ((i-2)*(i-1)*i)/6 + (i*(i-1))/2;///常数项; f = q; if((num+q)%p == 0) { if( (num+q)/p < i ) break;///只算一半即可; a[ans].m = i; a[ans++].n = (q+num)/p; if( (num+q)/p != i )///当两个数不相等时,反向保存; { a[ans].n = i; a[ans++].m = (num+q)/p; } } } sort(a, a+ans, cmp); printf("%d ", ans); for(int i=0; i<ans; i++) printf("%I64d %I64d ", a[i].n, a[i].m); } return 0; }