HNUST 1486: 小明的数学

1486: 小明的数学

时间限制: 1 Sec   内存限制: 128 MB
提交: 101   解决: 22
[ 提交][ 状态][ 讨论版]

题目描述

给一个整数n,你能告诉我有多少种方式写成:n = i * j + i + j (0 < i <= j)

输入

第一行T(<2000).接下来T行,每行一个整数n.

输出

一行一个整数。

这题也算一个水题吧,找到了关键才能AC,可惜楼主也是交了五六次才AC了。。。

思路:上来首先吐槽一下出题者,不说n的范围。这题一开始我就找了一下规律,打了个表。规律显然,自己看图。

所以我就先写成矩阵模式,大家看的懂一些

3 5 7 9 11 13 15

5 8 11 14 17 20 23

7 11 15 19 23 27 31

....不想打字了,懒

显然每一行都是一个等差数列,并且首项也是等差的,这就好办了。我第一想法是看n是否在每一行中,复杂度O(n/2),华丽丽的TLE了,

后来我就改变了策略,先看主对角线(主对角线不懂得看看离散数学),他就是i==j构成的,简化就是i(i+2),如果在的话 ,sum++,在以对角线

后一元素为起点(首项),判断是否在这一行,这样递增的速度就大幅增加,不会超时了,然后就是等差数嘛,公式很好推,行数从一开始,每一行

首元素就是i(i+1)-1,公差就是i,我用LL 花了600ms,换了int好像200ms就AC了。。。上代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
int main()
{
    int T,n,sum,k;
    scanf("%lld",&T);
    while(T--)
    {
        sum=0;
        scanf("%d",&n);
        k=floor(sqrt(n*1.0));
        if(k*(k+2)==n) sum=1;
        for(int i=2; n>=(i+1)*i-1; i++) ///for就是找右边的元素,是否在这一行
        if((n-((i+1)*i-1))%i==0)  sum++;///刚开始我是吧它乘以2,因为i,j是对称的,上方有,下方就有
        printf("%d\n",sum);             ///然后三次WA (⊙o⊙)…,后来一看题,i<=j。。。
                                               ///所以就砍掉了一半数据,不用乘以2咯
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值