暑假培训第一天 :sort+结构体+简单数学+暴力

本文精选了多道算法竞赛题目,涵盖排序、贪心算法、数据结构等核心内容,通过实战案例详细解析解题思路与技巧。

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

A:
题源:前m大的数

题目:

还记得Gardon给小希布置的那个作业么?(上次比赛的1005)其实小希已经找回了原来的那张数表,现在她想确认一下她的答案是否正确,但是整个的答案是很庞大的表,小希只想让你把答案中最大的M个数告诉她就可以了。
给定一个包含N(N<=3000)个正整数的序列,每个数不超过5000,对它们两两相加得到的N*(N-1)/2个和,求出其中前M大的数(M<=1000)并按从大到小的顺序排列。
Input
输入可能包含多组数据,其中每组数据包括两行:
第一行两个数N和M,
第二行N个数,表示该序列。

Output
对于输入的每组数据,输出M个数,表示结果。输出应当按照从大到小的顺序排列。
Sample Input
4 4
1 2 3 4
4 5
5 3 6 4
Sample Output
7 6 5 5
11 10 9 9 8

思路:
这道题只需要通过暴力循环把所有的数两两配对相加的和储存起来就行;然用sort排序,并且自定义排序cmp;
AC代码;

#include<bits/stdc++.h>
using namespace std;
int N,M;
int a[3010];
int b[3010*3010];
int x=0;
bool cmp(int a,int b)
{
	return a>b;
}
int main()
{
	while(cin >>N>>M)
	{
		x=0;
		for(int i=0;i<N;i++)
		{
			cin >>a[i];
		}
		for(int i=0;i<N;i++)
		{
			for(int j=i+1;j<N;j++)//j从i+1开始保证了两个数不会重复相加
			{
				b[x++]=a[i]+a[j];
			}
		}
		sort(b,b+N*(N-1)/2,cmp);//注意,因为从n个数里面挑出来两个数是C(n,2);
		for(int i=0;i<M;i++)
		{
			if(i==0) cout <<b[0];
			else cout <<" "<<b[i];
		}
		cout <<endl;
	}
	return 0;
}

B.
题源:B - 稳定排序
题目:
大家都知道,快速排序是不稳定的排序方法。
如果对于数组中出现的任意a[i],aj,其中a[i]==a[j],在进行排序以后a[i]一定出现在a[j]之前,则认为该排序是稳定的。

某高校招生办得到一份成绩列表,上面记录了考生名字和考生成绩。并且对其使用了某排序算法按成绩进行递减排序。现在请你判断一下该排序算法是否正确,如果正确的话,则判断该排序算法是否为稳定的。
Input
本题目包含多组输入,请处理到文件结束。
对于每组数据,第一行有一个正整数N(0<N<300),代表成绩列表中的考生数目。
接下来有N行,每一行有一个字符串代表考生名字(长度不超过50,仅包含’a’~‘z’),和一个整数代表考生分数(小于500)。其中名字和成绩用一个空格隔开。
再接下来又有N行,是上述列表经过某排序算法以后生成的一个序列。格式同上。
Output
对于每组数据,如果算法是正确并且稳定的,就在一行里面输出"Right"。如果算法是正确的但不是稳定的,就在一行里面输出"Not Stable",并且在下面输出正确稳定排序的列表,格式同输入。如果该算法是错误的,就在一行里面输出"Error",并且在下面输出正确稳定排序的列表,格式同输入。

注意,本题目不考虑该排序算法是错误的,但结果是正确的这样的意外情况
Sample Input
3
aa 10
bb 10
cc 20
cc 20
bb 10
aa 10
3
aa 10
bb 10
cc 20
cc 20
aa 10
bb 10
3
aa 10
bb 10
cc 20
aa 10
bb 10
cc 20
Sample Output
Not Stable
cc 20
aa 10
bb 10
Right
Error
cc 20
aa 10
bb 10

思路:
这一题的关键之处,最最关键之处,就是这句话:如果对于数组中出现的任意a[i],aj,其中a[i]==a[j],在进行排序以后a[i]一定出现在a[j]之前,则认为该排序是稳定的。这道题因为读题不认真wa了好长时间,一定要认真读题;
首先用结构体储存学生的姓名和成绩(同时给每一个同学出现的次序编号);然后在自己编写一个sort的cmp就行排序;排序的时候注意,分数不同按照从大到小排列,分数相同的按次序从小到大排列;
AC代码:

#include<bits/stdc++.h>
#include<string.h>
using namespace std;
int n;
struct node
{
	int ans;
	char s[51];
	int x;
}bb[510],aa[510],cc[510];
bool cmp(node a,node b)
{
	if(a.x==b.x) return a.ans<b.ans;
	return a.x>b.x;
}
int main()
{
	while(~scanf("%d",&n))
	{
		int flag=0,cot=0;
		for(int i=0;i<n;i++)
		{
			scanf("%s %d",&bb[i].s,&bb[i].x);
			bb[i].ans=i;
		}
		sort(bb,bb+n,cmp);
		for(int i=0;i<n;i++)
		{
			scanf("%s %d",&aa[i].s,&aa[i].x);
			aa[i].ans=i;
		}
	for(int i=0;i<n;i++)
	{
		if(bb[i].x!=aa[i].x)
		{
			flag=1;
			break;
		}
		if(strcmp(bb[i].s,aa[i].s)!=0) cot=1;
	}
	if(flag==1) {
	cout <<"Error"<<endl;
	for(int i=0;i<n;i++)
		{
			cout <<bb[i].s<<" "<<bb[i].x<<endl;
		}
	}
	else if(!flag&&!cot) cout <<"Right"<<endl;
	else
	{
		cout <<"Not Stable"<<endl;
		for(int i=0;i<n;i++)
		{
			cout <<bb[i].s<<" "<<bb[i].x<<endl;
		}
	}
}
	return 0;
}

C.
题源:开门人和关门人
题目:
每天第一个到机房的人要把门打开,最后一个离开的人要把门关好。现有一堆杂乱的机房签
到、签离记录,请根据记录找出当天开门和关门的人。
Input
测试输入的第一行给出记录的总天数N ( > 0 )。下面列出了N天的记录。
每天的记录在第一行给出记录的条目数M ( > 0 ),下面是M行,每行的格式为

证件号码 签到时间 签离时间

其中时间按“小时:分钟:秒钟”(各占2位)给出,证件号码是长度不超过15的字符串。
Output
对每一天的记录输出1行,即当天开门和关门人的证件号码,中间用1空格分隔。
注意:在裁判的标准测试输入中,所有记录保证完整,每个人的签到时间在签离时间之前,
且没有多人同时签到或者签离的情况。
Sample Input
3
1
ME3021112225321 00:00:00 23:59:59
2
EE301218 08:05:35 20:56:35
MA301134 12:35:45 21:40:42
3
CS301111 15:30:28 17:00:10
SC3021234 08:00:00 11:25:25
CS301133 21:45:00 21:58:40
Sample Output
ME3021112225321 ME3021112225321
EE301218 MA301134
SC3021234 CS301133

思路:
当然还是用结构体储存每个人的信息,在记录时间的时候可以把时间全部化为秒更为简便;当然也可以把表示时间的一串字符看成字符串,比较时比较字符串大小即可;然后自定义cmp即可

AC代码:

include<bits/stdc++.h>
using namespace std;
struct node
{
	char sss[20];
	int star;
	int end;
}bb[110];
bool cmp(node a,node b)
{
	return a.star<b.star;
}
bool cmpp(node a,node b)
{
	return a.end>b.end;
}
int main()
{
	int n;
	while(cin >>n)
	{
		while(n--)
		{
			int m;
			int a,b,c;
			cin >>m;
			for(int i=0;i<m;i++)
			{
				scanf("%s %d:%d:%d", &bb[i].sss, &a, &b, &c);
				bb[i].star=a*3600+b*60+c;
				scanf("%d:%d:%d",&a, &b, &c);
				bb[i].end=a*3600+b*60+c;
				
			}
			sort(bb,bb+m,cmp);
			printf("%s ",bb[0].sss);
			sort(bb,bb+m,cmpp);
			printf("%s\n",bb[0].sss);
		}
	}
	return 0;
}

D.
题源:D - EXCEL排序
题目:

Excel可以对一组纪录按任意指定列排序。现请你编写程序实现类似功能。
Input
测试输入包含若干测试用例。每个测试用例的第1行包含两个整数 N (<=100000) 和 C,其中 N 是纪录的条数,C 是指定排序的列号。以下有 N
行,每行包含一条学生纪录。每条学生纪录由学号(6位数字,同组测试中没有重复的学号)、姓名(不超过8位且不包含空格的字符串)、成绩(闭区间[0, 100]内的整数)组成,每个项目间用1个空格隔开。当读到 N=0 时,全部输入结束,相应的结果不要输出。
Output
对每个测试用例,首先输出1行“Case i:”,其中 i 是测试用例的编号(从1开始)。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3
时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。
Sample Input
3 1
000007 James 85
000010 Amy 90
000001 Zoe 60
4 2
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 98
4 3
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 90
0 0
Sample Output
Case 1:
000001 Zoe 60
000007 James 85
000010 Amy 90
Case 2:
000010 Amy 90
000002 James 98
000007 James 85
000001 Zoe 60
Case 3:
000001 Zoe 60
000007 James 85
000002 James 90
000010 Amy 90

思路:
同样用结构体储存学生的信息;
根据题中所给C的三种不同情况下的排序,可以编写三种cmp;注意题中非递减的意思就是递增;
输出格式上注意Case i中i递增的问题;
AC代码:

#include<bits/stdc++.h>
#include<string.h>
using namespace std;
typedef long long int ll;
const int max=1e6+7;
int N,C;
struct node 
{
	int x;
	char s[10];
	int y;
}bb[100001];
bool cmp1(node a,node b)
{
	return a.x<b.x;
}
bool cmp2(node a,node b)
{
	if(strcmp(a.s,b.s)==0) return a.x<b.x;
	return strcmp(a.s,b.s)<0;
}
bool cmp3(node a,node b)
{
	if(a.y==b.y) return a.x<b.x;
	return a.y<b.y;
}
int main()
{
	int x=0;
	while(cin >>N>>C)
	{
		if(N==0) break;
		for(int i=0;i<N;i++)
		{
			cin >>bb[i].x>>bb[i].s>>bb[i].y;
		}
		if(C==1)
		{
			sort(bb,bb+N,cmp1);
			cout <<"Case "<<++x<<":"<<endl;
			for(int i=0;i<N;i++)
			{
				printf("%06d %s %d\n",bb[i].x,bb[i].s,bb[i].y);
			}
		}
		else if(C==2)
		{
			sort(bb,bb+N,cmp2);
			cout <<"Case "<<++x<<":"<<endl;
			for(int i=0;i<N;i++)
			{
				printf("%06d %s %d\n",bb[i].x,bb[i].s,bb[i].y);
			}
		}
		else if(C==3)
		{
			sort(bb,bb+N,cmp3);
			cout <<"Case "<<++x<<":"<<endl;
			for(int i=0;i<N;i++)
			{
				printf("%06d %s %d\n",bb[i].x,bb[i].s,bb[i].y);
			}
		}
	}
	return 0;
}

E:
题源:统计同成绩学生人数
题目:
读入N名学生的成绩,将获得某一给定分数的学生人数输出。
Input
测试输入包含若干测试用例,每个测试用例的格式为

第1行:N
第2行:N名学生的成绩,相邻两数字用一个空格间隔。
第3行:给定分数

当读到N=0时输入结束。其中N不超过1000,成绩分数为(包含)0到100之间的一个整数。
Output
对每个测试用例,将获得给定分数的学生人数输出。
Sample Input
3
80 60 90
60
2
85 66
0
5
60 75 90 55 75
75
0
Sample Output
1
0
2

Huge input, scanf is recommended.
Hint
Hint

思路:
此题较水,但是需要注意的一点是题中给的注意:Huge input, scanf is recommended.(大量输入,建议使用scanf。)
可以直接暴力数得大于一个分数的人数;也可以排序后再数;

AC代码:

#include<bits/stdc++.h>
using namespace std;
int x[10000];
int main()
{
	int n;
	while(scanf("%d",&n),n)
	{
		int cot=0;
		int ans,i;
		for( i=0;i<n;i++)
			cin >>x[i];
		cin >>ans;
		for( i=0;i<n;i++)
		if(ans==x[i])
			cot++;
		cout<<cot<<endl;
	}
	return 0;
}

F.
题源:What Is Your Grade?
题目:

“Point, point, life of student!”
This is a ballad(歌谣)well known in colleges, and you must care about your score in this exam too. How many points can you get? Now, I told you the rules which are used in this course.
There are 5 problems in this final exam. And I will give you 100 points if you can solve all 5 problems; of course, it is fairly difficulty for many of you. If you can solve 4 problems, you can also get a high score 95 or 90 (you can get the former(前者) only when your rank is in the first half of all students who solve 4 problems). Analogically(以此类推), you can get 85、80、75、70、65、60. But you will not pass this exam if you solve nothing problem, and I will mark your score with 50.
Note, only 1 student will get the score 95 when 3 students have solved 4 problems.
I wish you all can pass the exam!
Come on!
Input
Input contains multiple test cases. Each test case contains an integer N (1<=N<=100, the number of students) in a line first, and then N lines follow. Each line contains P (0<=P<=5 number of problems that have been solved) and T(consumed time). You can assume that all data are different when 0<p.
A test case starting with a negative integer terminates the input and this test case should not to be processed.
Output
Output the scores of N students in N lines for each case, and there is a blank line after each case.
Sample Input
4
5 06:30:17
4 07:31:27
4 08:12:12
4 05:23:13
1
5 06:30:17
-1
Sample Output
100
90
90
95

100

思路:
这道题不难,但是wa…lit…的我生无可恋…
AC代码:

#include<bits/stdc++.h>
#include<string.h>
using namespace std;
typedef long long int ll;
const int max=1e6+7;
struct node
{
	int id;
	int x;
	int t;
	int score;
}bb[101];//用结构体储存学生的信息
bool cmp(node a,node b)
{
	if(a.x==b.x) return a.t>b.t;
	return a.x>b.x;
}
bool cmpp(node a,node b)
{
	return a.id<b.id;
}
int main()
{
	int n;
	while(~scanf("%d",&n)&&n!=-1)//这个地方特别要注意!!题中说n==-1时输入结束,而我没有进行判断,导致一直超时超时..
	{
		int cot1=0,cot2=0,cot3=0,cot4=0;

		for(int i=0;i<n;i++)
		{
			int a,b,c;
		scanf("%d %d:%d:%d",&bb[i].x,&a,&b,&c);
		bb[i].t=a*3600+b*60+c;//时间换算成秒;
		bb[i].id=i;//给每一个学生出现的顺序进行标记;因为输出学生成绩时是按学生出现的次序,所以需要提前标记
			if(bb[i].x==4)
			{
				cot4++;//把每一次每个分数出现的次数累加并记录
			}
			else if(bb[i].x==3)
			{
				cot3++;
			}
			else if(bb[i].x==2)
			{
				cot2++;
			}
			else if(bb[i].x==1)
			{
				cot1++;
			}

		}
		sort(bb,bb+n,cmp);//按照题的意思进行排序
		int a=cot4/2,b=cot3/2,c=cot2/2,d=cot1/2;
		for(int i=0;i<n;i++)
		{
			if(bb[i].x==5) bb[i].score=100;
			if(bb[i].x==0) bb[i].score=50;
			if(bb[i].x==4)
			{
				if(cot4>a){ bb[i].score=90;//前一半学生得高分,后又一半学生得分。例:4/2=2,则后两名低分,7/2=3,7-3=4,后
											//四名低分,前三名高分
				cot4--;
			}
				else bb[i].score=95;
			}
			else if(bb[i].x==3)
			{
				if(cot3>b) {
				bb[i].score=80;
				cot3--;
				}
				else bb[i].score=85;
			}
			else if(bb[i].x==2)
			{
				if(cot2>c) {
					bb[i].score=70;
					cot2--;
				}
				else bb[i].score=75;
			}
			else if(bb[i].x==1)
			{
				if(cot1>d) {
					bb[i].score=60;
					cot1--;
				}
				else bb[i].score=65;
			}
		}
		sort(bb,bb+n,cmpp);//按照出现的顺序就行排序之后再输出
		for(int i=0;i<n;i++)
		{
			cout <<bb[i].score<<endl;
		}
		cout <<endl;
	}
	return 0;
}

G.
题源: Magical Bamboos
题目:

In a magical forest, there exists N bamboos that don’t quite get cut down the way you would expect.

Originally, the height of the ith bamboo is equal to hi. In one move, you can push down a bamboo and decrease its height by one, but this move magically causes all the other bamboos to increase in height by one.

If you can do as many moves as you like, is it possible to make all the bamboos have the same height?

Input
The first line of input is T – the number of test cases.

The first line of each test case contains an integer N (1 ≤ N ≤ 105) - the number of bamboos.

The second line contains N space-separated integers hi (1 ≤ hi ≤ 105) - the original heights of the bamboos.

Output
For each test case, output on a single line "yes” (without quotes), if you can make all the bamboos have the same height, and “no” otherwise.

Example
Input
2
3
2 4 2
2
1 2
Output
yes
no

思路:
这道题需要一个巧妙地思维发现一个巧妙地规律;很遗憾 我并没有发现。哈哈哈哈没脸没皮。。大意就是你让一棵竹子的高度减一,其他的竹子高度都能加1,问能不能经过一一列的操作使得所有竹子一样高;假设一棵竹子高2 另外一棵竹子高4,你让高的减1,那么这棵低的就加一,所以就一样高了。由此得来所有竹子的高度差都为偶数,也就是所有竹子要么都是偶数要么都是奇数,只有这种情况才成立;

AC代码:

#include<bits/stdc++.h>
#include<string.h>
using namespace std;
typedef long long int ll;
const int max=1e6+7;
int a[100010];
int main()
{
    int t;
    cin >>t;
    while(t--)
    {
        int n;
        cin >>n;
        int x=0,y=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            if(a[i]%2==0) x++;
            if(a[i]%2==1) y++;
        }
        if(x==n||y==n) cout <<"yes"<<endl;
        else cout <<"no"<<endl;
    }
	return 0;
}

H.
题源:Bear and Three Balls
题目:

Limak is a little polar bear. He has n balls, the i-th ball has size ti.

Limak wants to give one ball to each of his three friends. Giving gifts isn’t easy — there are two rules Limak must obey to make friends happy:

No two friends can get balls of the same size.
No two friends can get balls of sizes that differ by more than 2.
For example, Limak can choose balls with sizes 4, 5 and 3, or balls with sizes 90, 91 and 92. But he can’t choose balls with sizes 5, 5 and 6 (two friends would get balls of the same size), and he can’t choose balls with sizes 30, 31 and 33 (because sizes 30 and 33 differ by more than 2).

Your task is to check whether Limak can choose three balls that satisfy conditions above.

Input
The first line of the input contains one integer n (3 ≤ n ≤ 50) — the number of balls Limak has.

The second line contains n integers t1, t2, …, tn (1 ≤ ti ≤ 1000) where ti denotes the size of the i-th ball.

Output
Print “YES” (without quotes) if Limak can choose three balls of distinct sizes, such that any two of them differ by no more than 2. Otherwise, print “NO” (without quotes).

Examples
Input
4
18 55 16 17
Output
YES
Input
6
40 41 43 44 44 44
Output
NO
Input
8
5 972 3 4 1 4 970 971
Output
YES
Note
In the first sample, there are 4 balls and Limak is able to choose three of them to satisfy the rules. He must must choose balls with sizes 18, 16 and 17.

In the second sample, there is no way to give gifts to three friends without breaking the rules.

In the third sample, there is even more than one way to choose balls:

  1. Choose balls with sizes 3, 4 and 5.
  2. Choose balls with sizes 972, 970, 971.

**思路:**好吧 读题不认真的我做这道题的时候又是出错,我以为只要将输入的数据排序,找到有没有三个连续的数就可以知道结果了;但是 如果一个数如果同时出现了两次或者多次,那么就无法直接判断紧挨的三个数是否连续;所以我就wa了;
后来想到 我为啥不间接的把这个数组储存起来;用另外一个数组把每一个数出现过进行标记;如果相邻的三个数的都出现了;那么就ac了;

AC代码:

#include<bits/stdc++.h>
#include<string.h>
using namespace std;
typedef long long int ll;
const int max=1e6+7;
int w[1010];
int size[1010];
int main()
{
	int n;
	while(~scanf("%d",&n))
	{
		int flag=0;
		memset(size,0,sizeof(size));
		for(int i=0;i<n;i++)
		{
			cin >>w[i];
			size[w[i]]=1;//对出现的数进行标记
		}
		for(int i=0;i<1010;i++)
		{
			if(size[i]&&size[i+1]&&size[i+2]) flag=1;//如果连续三个数都被标记过了就满足条件
		}
		if(flag) cout <<"YES"<<endl;
		else cout <<"NO"<<endl;
	}
}

I.
题源:http://acm.hdu.edu.cn/showproblem.php?pid=2037
题目:

“今年暑假不AC?”
“是的。”
“那你干什么呢?”
“看世界杯呀,笨蛋!”
“@#$%^&*%…”

确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视了。
作为球迷,一定想看尽量多的完整的比赛,当然,作为新时代的好青年,你一定还会看一些其它的节目,比如新闻联播(永远不要忘记关心国家大事)、非常6+7、超级女生,以及王小丫的《开心辞典》等等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目)
Input
输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。
Output
对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。
Sample Input
12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0
Sample Output
5

思路:
这一题是典型的的贪心;如果我要看更多的节目,首先想到的是节目短一点,我是不是就看得多了;确实是这样,但有时候这个节目虽然短但是会和其他节目起冲突,所以不好判断;我们可以先把结束的时间从小到大排列,同时如果结束时间相等就让开始时间从大到小;意思就是,那个节目结束的早就看那个节目,同时看的下一个节目要满足开始时间大于等于看的上一个节目;
AC代码

#include<bits/stdc++.h>
using namespace std;
int n;
struct node
{
	int x;
	int y;
}bb[110];
int ss[100];
bool cmp(node a,node b)
{
	if(a.y==b.y) return a.x>b.x;
	return a.y<b.y;
}
bool cmpp(int x,int y)
{
	return x>y;
}
int main()
{
	while(cin >>n)
	{
		int sum=1;
		if(!n) break;
		for(int i=0;i<n;i++)
		{
			cin >>bb[i].x>>bb[i].y;
		}
		sort(bb,bb+n,cmp);//那个节目结束的早就看那个节目
		int temp=0;
		for(int i=1;i<n;i++)
		{
			if(bb[temp].y<=bb[i].x)//看的下一个节目要满足开始时间大于等于看的上一个节目;
			{
				sum++;
				temp=i;
			}
		}
		cout <<sum<<endl;
	}
	return 0;
}

J.
题源:The sum problem
题目:

Given a sequence 1,2,3,…N, your job is to calculate all the possible sub-sequences that the sum of the sub-sequence is M.
Input
Input contains multiple test cases. each case contains two integers N, M( 1 <= N, M <= 1000000000).input ends with N = M = 0.
Output
For each test case, print all the possible sub-sequence that its sum is M.The format is show in the sample below.print a blank line after each test case.
Sample Input
20 10
50 30
0 0
Sample Output
[1,4]
[10,10]

[4,8]
[6,9]
[9,11]
[30,30]

思路:
这道题感觉算是我到现在做过题中最具有思维性的一道题了,这道题根据等差数列的前n项和公式na+n(n-1)/2=m可以得出来,把;也就是说n<sqrt(m*2);然后,一一枚举从sqrt(m2)到1所有的n对应的a,如果a带入**na+n*(n-1)/2=m**成立,那么这时的a就是区间的左半边,右半边为a+n-1;(注意因为题目输出的关系,所以要从sqrt(m*2)开始到1倒着找满足条件的区间;
AC代码:

#include<bits/stdc++.h>
#include<string.h>
using namespace std;
typedef long long int ll;
const int max=1e6+7;
int main()
{
    int n,m;
    while(scanf("%d %d",&n,&m)&&(n||m))
    {
        int k=(int)pow(m*2,0.5);//也可以用sqrt()
        for(int i=k;i>=1&&i<n;i--)
        {
            int a=(m-i*(i-1)/2)/i;//求出此时n对应的a,注意此时a这是取整的结果
            if((i*a+i*(i-1)/2)==m)//判断a是否符合条件
            {
                printf("[%d,%d]\n",a,a+i-1);
            }
        }
        printf("\n");
    }
	return 0;
}

over

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值