B
而
所以直接判断
import java.util.Arrays;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int T=input.nextInt();
while(true) {
if(T==0) break;
int[] num=new int[3];
for(int i=0;i<3;++i)num[i]=input.nextInt();
Arrays.sort(num);
int m=input.nextInt();
int a=num[0];
int b=num[1];
int c=num[2];
int g=gcd(a, gcd(b, c));
if(m%g==0) {
System.out.println("YES");
}else System.out.println("NO");
T--;
}
}
public static int gcd(int a,int b) {
int res;
while(b!=0) {
res=a%b;
a=b;
b=res;
}
return a;
}
}
C
两两分组之和相等,所以最大值一定和最小值相加,否则比与最大值一组的那个数小的都无法满足。
所以判断条件即由小到大排号序后,1和n,2和n-1,……依次配对比较是否相同。
若都相同,则还需输出交换方法。
目标序列即为排序后的序列。
记录目标序列中相对应的原序列的下标。
最小的交换次数,一定是在一组轮换内依次交换,轮换组是一个循环,所以当要和进入时的下标交换时,退出循环。同时,对组内的所有数打上标记,避免重复进入轮换进行交换。
例:
3 5 1 4 7 => 1 3 4 5 7
1 3 4 5 7
下标:1 2 3 4 5
对应原数组下标:3 1 4 2 5
则轮换组为(1 3 4 2)(5)
所以交换为(1 3)(3 4)(4 2)
import java.util.Arrays;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int T=input.nextInt();
while(true) {
if(T==0) break;
int n=input.nextInt();
Node[] a=new Node[n+1];
for(int i=1;i<=n;++i) {
a[i]=new Node(input.nextInt(), i);
}
Arrays.sort(a,1,n+1,(o1,o2)->{return o1.x-o2.x;});
for(int i=1;i<=n;++i)a[i].end=i;
int sum=a[1].x+a[n].x;
boolean fl=false;
for(int i=2;i<=n/2;++i) {
if(a[i].x+a[n-i+1].x!=sum) {
fl=true;
break;
}
}
if(n%2!=0&&2*a[n/2+1].x!=sum) {
fl=true;
}
if(fl) {
System.out.println("NO");
T--;
continue;
}
int m=0;
Node[] sw=new Node[n+1];
boolean[] vis=new boolean[n+1];
for(int i=1;i<=n;++i) {
int t=i;
while(a[t].begin!=i&&vis[t]!=true) {
m++;
sw[m]=new Node(a[t].end, a[t].begin);
vis[t]=true;
t=a[t].begin;
}
vis[t]=true;
}
System.out.println("YES");
System.out.println(m);
for(int i=1;i<=m;++i) {
System.out.println(sw[i].x+" "+sw[i].begin);
}
T--;
}
}
}
class Node{
int x;
int begin;
int end;
public Node(int X,int B) {
x=X;
begin=B;
}
}
1361





