在数论中,裴蜀等式或裴蜀定理是一个关于最大公约数(或最大公约式)的定理。裴蜀定理得名于法国数学家艾蒂安·裴蜀,说明了对任何整数a、b和它们的最大公约数d,关于未知数x和y的线性丢番图方程(称为裴蜀等式):
Time Limit: 10 Sec | Memory Limit: 128 MB |
---|
jyy就一直想着尽快回地球,可惜他飞船的燃料不够了。有一天他又去向火星人要燃料,这次火星人答应了,要jyy用飞船上的瓶子来换。jyy的飞船上共有 N个瓶子(1<=N<=1000) ,经过协商,火星人只要其中的K 个 。 jyy将 K个瓶子交给火星人之后,火星人用它们装一些燃料给 jyy。所有的瓶子都没有刻度,只在瓶口标注了容量,第i个瓶子的容量为Vi(Vi 为整数,并且满足1<=Vi<=1000000000 ) 。火星人比较吝啬,他们并不会把所有的瓶子都装满燃料。他们拿到瓶子后,会跑到燃料库里鼓捣一通,弄出一小点燃料来交差。jyy当然知道他们会来这一手,于是事先了解了火星人鼓捣的具体内容。火星人在燃料库里只会做如下的3种操作:
1、将某个瓶子装满燃料;
2、将某个瓶子中的燃料全部倒回燃料库;
3、将燃料从瓶子a倒向瓶子b,直到瓶子b满或者瓶子a空。燃料倾倒过程中的损耗可以忽略。火星人拿出的燃料,当然是这些操作能得到的最小正体积。
jyy知道,对于不同的瓶子组合,火星人可能会被迫给出不同体积的燃料。jyy希望找到最优的瓶子组合,使得火星人给出尽量多的燃料。
第1行:2个整数N,K,
第2..N 行:每行1个整数,第i+1 行的整数为Vi
仅1行,一个整数,表示火星人给出燃料的最大值。
3 2
3
4
4
4
选择第2 个瓶子和第 个瓶子,火星人被迫会给出4 体积的容量。
裴蜀定理的应用,将每个数的因子进行排序,选出最大的因子,并且个数大于等于k就是答案
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int Max = 1e6+100;
int a[Max];
void Get(int x){
for(int i = 1;i*i<=x;i++){
if(x%i == 0) a[++a[0]] = i;
if(x%i == 0 && x/i!=i) a[++a[0]] = x/i;
}
}
int main(){
int n,x,k;
scanf("%d %d",&n,&k);
a[0] = 0;
for(int i = 0;i<n;i++){
scanf("%d",&x);
Get(x);
}
sort(a+1,a+a[0]+1);
int ans = 0;
int num = 1;
for(int i = a[0]-1;i>=1;i--){
if(a[i]==a[i+1]) num++;
else {
if(num>=k) {ans = a[i+1];break;}
num =1;
}
}
printf("%d\n",ans);
return 0;
}
Time Limit: 10 Sec | Memory Limit: 256 MB |
---|
给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a)这些向量,问你能不能拼出另一个向量(x,y)。
说明:这里的拼就是使得你选出的向量之和为(x,y)
第一行数组组数t,(t<=50000)
接下来t行每行四个整数a,b,x,y (−2×109<=a,b,x,y<=2×109)
t行每行为Y或者为N,分别表示可以拼出来,不能拼出来
3
2 1 3 3
1 1 0 1
1 0 -2 3
Y
N
Y
HINT
样例解释:
第一组:(2,1)+(1,2)=(3,3)
第三组:(-1,0)+(-1,0)+(0,1)+(0,1)+(0,1)=(-2,3)
通过观察可以发现,总共就四种操作 x±2a,y±2b,x+a,y+b,x+b,y+a ,也可以确定三四操作只会出现一次,那么我们枚举三四操作,根据裴蜀定理判断是否符合条件。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
#include <algorithm>
using namespace std;
typedef long long LL;
LL gcd(LL a,LL b) {
return b ==0?a:gcd(b,a%b);
}
LL ok(LL x,LL y,LL g) {
return (x%g ==0 && y%g ==0);
}
int main() {
LL a,b,x,y;
int T;
scanf("%d",&T);
while(T--) {
scanf("%lld %lld %lld %lld",&a,&b,&x,&y);
LL g = gcd(2*a,2*b);
if(ok(x,y,g)||ok(x+a,y+b,g)||ok(x+b,y+a,g)||ok(x+a+b,y+a+b,g)) printf("Y\n");
else printf("N\n");
}
return 0;
}