neuq 1096 NEUQ的邮票

该博客探讨了如何解决一个数学问题,即在给定不同面值的邮票中找到总价值为M且连续的邮票组合。通过分析等差数列的性质,提出了解决方案,强调了效率和正确性的关键点。
摘要由CSDN通过智能技术生成

题目描述:
neuq最近推出了一套具有特殊意义的邮票,邮票的价值是从1分到N分。并且每张邮票的价值都不相同。

谷学长看中了这套邮票,可是一掏兜发现自己只有M分。但是他非常想买,于是他决定买总价值刚好为M分的邮票,但谷学长不希望他买的邮票断断续续,所以他还希望能够买从x分到y分连续的y-x+1张邮票。

你的任务是求出所有符合要求的方案,以[x,y]的形式输出。

输入:
输入包含多组数据,每组数据只有一行,包含两个数N和M(1<=N,M<=10^9)。

输出:
对于每组输入数据,每行输出包含一个合法方案:[x,y]。按x值从小到大输出。

每组输出数据不含任何空格。

样例输入
20 15
样例输出
[1,5]
[4,6]
[7,8]
[15,15]
分析:开始考虑这道题是想用两层循环,外层遍历选定邮票首项,内层遍历之后的尾项,满足和为M。但是显然效率低下。
考虑到邮票是从1~N的等差数列排列,可以利用等差数列公式。
按照等差数列计算,连续数列有i个数,首数为x,和为n=(2x+i-1)*i/2,解得x=(2n/i-i+1)/2,注意x>0且i为整数,可得i的取值范围为[1, sqrt(2*n)],又x为整数,故2n/i为整数,且(2n/i-i+1)/2为整数。

#include"stdio.h"
#include"math.h"
int stamp(int n, int m);
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))//因为题目没有说明何时输入结束 所以以EOF为结束 最好用~ 因为用!EOF说内存超限 
    {
        stamp(n,m);
    }
    return 0;
}
int stamp(int n,int m)
{
    int temp,i;
    for(i = sqrt(2*m); i>=1; i--)//注意从i= 1 开始 而不是i= 2  否则不包含【m,m】 
    {
        if((2*m)%i==0)//即 2*m/i为一个整数 
        {
            temp = m*2/i-i+1;
            if(temp%2 == 0)//temp = 连续数列的首项的2倍 保证可以整除
            {
                if((temp/2+i-1)<=n)//保证连续邮票的尾项不超过总数 
                {
                    printf("[%d,%d]\n",temp/2,temp/2+i-1);
                }

            } 
        } 
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值