牛客练习赛120

B

m \ mod \ (ax+by+cz) == 0 \ \ \ \ x,y,z\in \mathbb{Z}

而 ax+by+cz \ \ mod \ \ gcd(a,b,c) =0

所以直接判断  m \ mod\ gcd(a.b.c)==0

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;
	}
}

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值