纪念邮票
题目描述
邮局最近推出了一套纪念邮票,这套邮票共有 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 b−a+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 1≤N,M≤109),之间用空格隔开。
输出格式
输出文件每行包含一个合法方案: [ 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;
}