bzoj 1407 //1407: [Noi2002]Savage 扩展欧几里得
bzoj 1407 //1407: [Noi2002]Savage //在线测评地址https://www.lydsy.com/JudgeOnline/problem.php?id=1407
//在线测评地址https://www.luogu.org/problem/P2421
更多题解,详见https://blog.csdn.net/mrcrack/article/details/90228694BZOJ刷题记录
Accepted | 820 kb | 1032 ms | C++/Edit | 1336 B |
//1407: [Noi2002]Savage
//在线测评地址https://www.lydsy.com/JudgeOnline/problem.php?id=1407
//在线测评地址https://www.luogu.org/problem/P2421
//题意清晰,怎么做呢。2019-11-17 13:57
//青蛙的约会,有2只青蛙,该题野人最多能到15个。
//此文http://hzwer.com/3297.html思路写得不错,摘抄如下
/*
枚举m>=max{c[i]}
使得对于每一对i,j
有c[i]+x*p[i]=c[j]+x*p[j] (mod m)
无解或者最小正整数解>min(l[i],l[j])
上式可以用exgcd求解
即(p[i]-p[j])*x-my=c[j]-c[i]
*/
//看了上述思路,想了想,枚举m确实没想到,野人两两比较想到了,却没敢去试。2019-11-17 14:56
//编写过程中,发现一个比较重大的错误,错误代码如下
/*
x=(x%b+b)%b;//保证x>=0
if(!x)x=b;//x=0要注意
x*=C;
应改成
x*=C;
x=(x%b+b)%b;//保证x>=0
if(!x)x=b;//x=0要注意
*/
//a=p[i]-p[j],b=m,C=c[j]-c[i];//此处错写成a=myabs(p[i]-p[j]),b=m,C=myabs(c[i]-c[j]);
//样例通过,提交Time_Limit_Exceed 816 kb 5000 ms C++/Edit 1161 B。2019-11-17 17:13
//该题有坑,存在d<0,导致b<0的情况
//b=myabs(b);//漏了该句,该题有坑,存在d<0,导致b<0的情况
//样例通过,提交AC。2019-11-17 17:23
#include
#define maxn 20
int c[maxn],p[maxn],l[maxn],n;
int myabs(int a){
return a>=0?a:-a;
}
int max(int a,int b){
return a>b?a:b;
}
int min(int a,int b){
return a }
int gcd(int a,int b){
return b?gcd(b,a%b):a;//此处错写成return b?a:gcd(b,a%b);
}
void exgcd(int a,int b,int *x,int *y){
int t;
if(b==0){
*x=1,*y=0;
return ;
}
exgcd(b,a%b,x,y);
t=*x,*x=*y,*y=t-a/b**y;//此处错写成t=*x,*x=*x-a/b**y,*y=t;
}
int judge(int m){
int i,j,a,b,C,d,x,y;//x延续年数
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++){
a=p[i]-p[j],b=m,C=c[j]-c[i];//此处错写成a=myabs(p[i]-p[j]),b=m,C=myabs(c[i]-c[j]);
d=gcd(a,b);
if(C%d)continue;//无解。
a/=d,b/=d,C/=d;//该题有坑,存在d<0,导致b<0的情况
exgcd(a,b,&x,&y);
x*=C;//写错顺序,要出问题。
b=myabs(b);//漏了该句,该题有坑,存在d<0,导致b<0的情况
x=(x%b+b)%b;//保证x>=0
if(!x)x=b;//x=0要注意
if(x<=min(l[i],l[j]))return 0;
}
return 1;
}
int main(){
int i,j,mx=0;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d%d%d",&c[i],&p[i],&l[i]),mx=max(mx,c[i]);
for(i=mx;;i++)
if(judge(i)){
printf("%d\n",i);
return 0;
}
}
模仿洛谷P1516 青蛙的约会https://www.luogu.org/problem/P1516写的代码
Accepted | 820 kb | 1396 ms | C++/Edit | 1188 B |
#include
#define maxn 20
int c[maxn],p[maxn],l[maxn],n;
int max(int a,int b){
return a>b?a:b;
}
int min(int a,int b){
return a }
int gcd(int a,int b){
return b?gcd(b,a%b):a;//此处错写成return b?a:gcd(b,a%b);
}
void exgcd(int a,int b,int *x,int *y){
int t;
if(b==0){
*x=1,*y=0;
return ;
}
exgcd(b,a%b,x,y);
t=*x,*x=*y,*y=t-a/b**y;//此处错写成t=*x,*x=*x-a/b**y,*y=t;
}
int judge(int m){
int i,j,a,b,C,d,x,y;//x延续年数
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++){
a=p[i]-p[j],b=m,C=c[j]-c[i];//此处错写成a=myabs(p[i]-p[j]),b=m,C=myabs(c[i]-c[j]);
a=(a%m+m)%m,C=(C%m+m)%m;
d=gcd(a,b);
if(C%d)continue;//无解。
a/=d,b/=d,C/=d;
exgcd(a,b,&x,&y);
x*=C;//写错顺序,要出问题。
x=(x%b+b)%b;//保证x>=0
if(!x)x=b;//x=0要注意
if(x<=min(l[i],l[j]))return 0;
}
return 1;
}
int main(){
int i,j,mx=0;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d%d%d",&c[i],&p[i],&l[i]),mx=max(mx,c[i]);
for(i=mx;;i++)
if(judge(i)){
printf("%d\n",i);
return 0;
}
}