小红拥有无穷的魔力,她可以对项链上的相邻两个珠子进行交换。小红希望用最小的交换次数,使得任意两个红色的珠子的最小距离不小于
,你能帮小红求出最小的交换次数吗?
第一行输入一个正整数,代表询问次数。
每行为一次询问,输出五个正整数,分别代表珠子总数量、要求的珠子距离,以及三个珠子的位置。
保证互不相同。
输出行,每行输入一个整数,代表最小的交换次数。如果无法完成目的,则输出-1。
2 6 2 1 2 3 5 2 1 3 4
2 -1
第一组样例,六个珠子为红红红白白白。第一次操作交换第一个和第六个珠子,第二次操作交换第三个和第四个珠子。第二组询问,一共有5个珠子,其中有3个红珠子,因此无论如何都会有两个红珠子相邻,不可能满足任意两个红珠子的最小距离不小于2。
fun getCycledDistance(a: Int, b: Int, n: Int): Int {
val distance = abs(b - a)
return min(distance, n - distance)
}
fun solve(n: Int, k: Int, a: Int, b: Int, c: Int): Long {
if (n < 3 * k) return -1
val points = mutableListOf(a, b, c)
points.sort()
val arcs = mutableListOf(
getCycledDistance(points[0], points[1], n),
getCycledDistance(points[0], points[2], n),
getCycledDistance(points[1], points[2], n)
)
if(false !in arcs.map { it >= k }) return 0
arcs.sort()
return Math.max(0, k - arcs[0]) + Math.max(0, k - arcs[1])
} 使用补全弧长法可以很快解题:#include <iostream>
using namespace std;
void sort(int &a1,int &a2,int &a3){
int t;
if(a1<a2&&a2<a3){
return ;
}
if(a1>a2){
t=a1,a1=a2,a2=t;
}
if(a1>a3){
t=a1,a1=a3,a3=t;
}
if(a2>a3){
t=a2,a2=a3,a3=t;
}
}
int main() {
int t;
cin>>t;
for(int i=0;i<t;i++){
int n,k,a1,a2,a3;
cin>>n>>k>>a1>>a2>>a3;
if(n/3<k){
cout<<"-1"<<endl;
continue;
}
else{
sort(a1,a2,a3);
int a12,a13,a23;
a12=a2-a1;
a23=a3-a2;
a13=n-a3+a1;
int t1=a12,t2=a23,t3=a13;
sort(t1,t2,t3);
cout<<max(0,k-t1)+max(0,k-t2)<<endl;
}
}
}