Spongebob and Squares---cf599D(数学公式1 + (1+2) + (1+2+3) +....)

题目链接: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\n", ans);

        for(int i=0; i<ans; i++)
            printf("%I64d %I64d\n", a[i].n, a[i].m);
    }
    return 0;
}
View Code

 

posted @ 2016-05-01 13:33  西瓜不懂柠檬的酸  Views(156)  Comments(0Edit  收藏  举报
levels of contents