P3910 纪念邮票(数学&规律)

文章讲述了如何为集邮爱好者小明找到在给定资金M的情况下,购买一套面值从a到b连续邮票的全部方案,使得总价值恰好等于M。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

纪念邮票

题目描述

邮局最近推出了一套纪念邮票,这套邮票共有 N N N 张,邮票面值各不相同,按编号顺序为 1 1 1 分, 2 2 2 分,……, N N N 分。

小明是个集邮爱好者,他很喜欢这套邮票,可惜现在他身上只有 M M M 分,并不够把全套都买下,但是他希望刚好花光所有的钱。作为一个集邮爱好者,小明也不想买的邮票编号断断续续,所以小明打算买面值 a a a 分至 b b b 分的 b − a + 1 b-a+1 ba+1 张连续的邮票,且总价值刚好为 M M M 分。

你的任务是求出所有符合要求的方案,以 [ a , b ] \left[a,b\right] [a,b] 的形式输出。

输入格式

输入文件只有一行。包含两个整数 N N N M M M 1 ≤ N , M ≤ 1 0 9 1\le N,M \le 10^9 1N,M109),之间用空格隔开。

输出格式

输出文件每行包含一个合法方案: [ a , b ] \left[a,b\right] [a,b],按 a a a 值从小到大输出。

样例 #1

样例输入 #1

20 15

样例输出 #1

[1,5]
[4,6]
[7,8]
[15,15]

解析

区间个数从1开始枚举,查看是否符合即可。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+5;
int n,m;
void solve(){
	scanf("%lld%lld",&n,&m);
	vector<pair<int,int>>res;
	int cnt=0;
	for(int i=1;i<=n;i++){
		if(i%2==1){
			if(m%i==0){
				int x=m/i;
				if(x-i/2>=1&&x+i/2<=n){
					res.push_back({x-i/2,x+i/2});
				}
			}
		}
		else{
			if((m-(i/2))%i==0){
				int x=(m-(i/2))/i;
				if(x-(i/2)+1>=1&&x+i/2<=n){
					res.push_back({x-(i/2)+1,x+i/2});
				}
			}
		}
		cnt+=i;
		if(cnt>n) break;
	}
	sort(res.begin(),res.end());
	for(int i=0;i<res.size();i++){
		printf("[%lld,%lld]\n",res[i].first,res[i].second);
	}
}
signed main(){
	int t=1;
//	scanf("%lld",&t);
	while(t--) solve();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值