CodeForces 599D Spongebob and Squares(DP+math)

2 篇文章 0 订阅

Spongebob and Squares
Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Submit

Status

Practice

CodeForces 599D
Description
Spongebob is already tired trying to reason his weird actions and calculations, so he simply asked you to find all pairs of n and m, such that there are exactly x distinct squares in the table consisting of n rows and m columns. For example, in a 3 × 5 table there are 15 squares with side one, 8 squares with side two and 3 squares with side three. The total number of distinct squares in a 3 × 5 table is 15 + 8 + 3 = 26.

Input
The first line of the input contains a single integer x (1 ≤ x ≤ 1018) — the number of squares inside the tables Spongebob is interested in.

Output
First print a single integer k — the number of tables with exactly x distinct squares inside.

Then print k pairs of integers describing the tables. Print the pairs in the order of increasing n, and in case of equality — in the order of increasing m.

Sample Input
Input
26
Output
6
1 26
2 9
3 5
5 3
9 2
26 1
Input
2
Output
2
1 2
2 1
Input
8
Output
4
1 8
2 3
3 2
8 1
Hint
In a 1 × 2 table there are 21 × 1 squares. So, 2 distinct squares in total.

In a 2 × 3 table there are 61 × 1 squares and 22 × 2 squares. That is equal to 8 squares in total.

题意:
给一个x,问哪些矩阵中一共有x个正方形。输出符合条件所有的矩阵。
分析:
这题是讲了才会。。。思考了一下为什么当时没有做出来,其实是自己忽略了一个关键的问题:对于每一个确定r(行数)其实只会有一个c(列数) 使得r*c符合条件。
所以只用枚举行数然后通过公式判断 是否有c 就可以了。
公式的推导是DP的思想。

{因为r*c 和 c*r 是一样的,所以我们只考虑行数小于等于列数的情况,r≤c}
定义f(r,c)为r*c 这个矩阵所含有的正方形数。
f(r,c)=f(r,c-1)+r*(r+1)/2; 因为只增加了一列,所以只考虑增加这一列会带来的影响。
r

//  Created by ZYD in 2015.
//  Copyright (c) 2015 ZYD. All rights reserved.
//

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define Size 100000
#define ll long long
#define mk make_pair
#define pb push_back
#define mem(array) memset(array,0,sizeof(array))
typedef pair<int,int> P;
struct type{
    ll l;
    ll r;
}ans[1000006];
ll x,tot;
int flag=0;
ll js(ll i){
    // cout<<i*(i+1)*(2*i+1)/6<<endl;
    // ll p=i*(i+1)*(2*i+1)/6;
    return (i*(i+1)*(2*i+1)/6);
}
int main()
{
    freopen("in.txt","r",stdin);
    scanf("%lld\n",&x);
    ll i=1;
    while(js(i)<=x){
        ll temp=js(i);
        ll mo=i*(i+1)/2;
        // cout<<temp<<" "<<mo<<endl;
        if((x-temp)%mo ==0 ){
            tot++;
            ans[tot].l=i;
            ans[tot].r=i+(x-temp)/mo;
            if(x==temp) flag=1;
        }
        i++;
    }
    if(flag) printf("%lld\n",tot*2-1);
    else printf("%lld\n",tot*2);
    for(i=1;i<=tot;i++){
        printf("%lld %lld\n",ans[i].l,ans[i].r);
    }
    if(flag) tot--;
    for(i=tot;i>=1;i--){
        printf("%lld %lld\n",ans[i].r,ans[i].l);
    }
    return 0;   
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值