学生排队问题

有n个学生站成一排。但其中有两个学生是死对头。第一个学生的位置是a,第二个学生的位置是b。位置的标号从左到右依次为1~n。

作为一名教师, 你的责任是让他们尽可能地远离彼此,永远不要在一起。他们之间距离的计算式子为|a - b|。

你可以交换相邻的两个学生x次。请你计算在交换最多x次后这两名学生的距离。

输入:

第一行包含一个数字 t (1≤t≤100) — 测试用例个数。

每一个用例包含四个数字 n, x, a 和 b (2≤n≤100, 0≤x≤100, 1≤a,b≤n, a≠b) 分别是学生数、你能交换的次数和两个死对头的位置。

输出:

每一个用例输出你能让两个学生分开的最大距离。

测试用例:

3
5 1 3 2
100 33 100 1
6 0 2 3

2
99
1

要想求出两个同学之间的最大距离(无非就是靠左的同学往左走靠右的同学往右走,每次移动一下),我们可以选定一个同学让他一直往左或往右移动。例如:先让a同学和b同学比大小,假如a同学靠右边,则我让a同学一直向右移动,并记录移动次数,如果移动次数与a同学初始位置相加小于总人数,则a-b就是两人的最大距离,如果移动次数与a同学初始位置相加大于总人数,则a为最大人数,而移动次数就变为初始的移动次数减去a移动到最大人数的次数,再让b同学初始位置减去移动次数,如果b同学初始位置减去移动次数大于等于1,则a-b就是最大距离,如果b同学初始位置减去移动次数小于1,则让b同学的位置等于1,多余的移动次数没用,此时a同学和b同学的位置已经在队伍的最左和最右边。

#include<stdio.h>
#include <stdlib.h>
int main(){
	int t,n,x,a,b,sum[100]={0};
	scanf("%d",&t);
	for(int i=0;i<t;i++){
		scanf("%d%d%d%d",&n,&x,&a,&b);
		if(a>b){//选出最大值 
			if((a+x)<=n){//当最大值加上移动次数小于最右边的位置时 
				sum[i]=abs((a+x)-b);
			}
			else{//当最大值加上移动次数大于最右边的位置时 
				x=x-(n-a); //还剩下的移动次数 
				a=n;
				if((b-x)>=1){//当最小值减去移动次数大于1时 
					sum[i]=abs(a-(b-x));
				}
				else{
					b=1;
					sum[i]=abs(a-b); 
				} 
			}
		}
		else{
			if((b+x)<=n){
				sum[i]=abs((b+x)-a);
			}
			else{//当最大值加上移动次数大于最右边的位置时 
				x=x-(n-b); //还剩下的移动次数
				b=n; 
				if((a-x)>=1){//当最小值减去移动次数大于1时 
					sum[i]=abs(b-(a-x));
				}
				else{
					a=1;
					sum[i]=abs(a-b); 
				} 
			}

		} 	
	}
	for(int i=0;i<t;i++){
		printf("%d\n",sum[i]);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值