[构造] BZOJ 1530 [POI2005]Sko-knight Knights

论文:陈启峰--一张一弛,解题之道

觉得论文里的图有点问题 不过思路很棒


注意到,如果任意的三个向量都可以与某两个向量等价,那么便可以从n(n>2)个向量中任选三个向量出来,用与它们等价的两个向量代替它们,从而变成n-1个向量。不断重复上述的过程,直到只剩下两个向量为止,这时剩下的两个向量便是一个可行解。而由问题描述可以知道:对于任意三个向量都存在两个向量与它们等价。这便意味这种方法是可行的。








BZOJ上没有SPJ 没过 但原题过了 

传送门:http://main.edu.pl/en/archive/oi/12/sko




#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

inline void exgcd(int a,int b,int &x,int &y){
  if (b==0){ x=1; y=0; return; }
  exgcd(b,a%b,x,y);
  int tem=y; y=x-a/b*y; x=tem;
}

inline void solve(int a1,int b1,int a2,int b2,int &x,int &y,int &y2){
  if (!a1) { x=a2; y=b2; y2=b1; }
  if (!a2) { x=a1; y=b1; y2=b2; }
  int p,q,d;
  exgcd(a1,a2,p,q); d=p*a1+q*a2;
  x=d; y=p*b1+q*b2;
  y2=abs(a1*b2-a2*b1)/d;
}

int n,a[105],b[105];

int main(){
  freopen("t.in","r",stdin);
  freopen("t.out","w",stdout);
  scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d%d",a+i,b+i);
  int x,y,y2,tem;
  solve(a[1],b[1],a[2],b[2],x,y,y2);
  for (int i=3;i<=n;i++){
    tem=y2;
    solve(a[i],b[i],x,y,x,y,y2);
    y2=__gcd(y2,tem);
  }
  printf("%d %d\n%d %d\n",x,y,0,y2);
  return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值