YACS 2023年8月月赛 甲组 T2 直线整点 题解

题目链接

简单题,先二分出直线上 x 最小的点使得这个点在矩形内。

然后不断跳,直到遇到整点。(实际上要用扩欧,但初测能过于是就偷个懒没写,upd:终测也过了) 

接着不断跳 x 直到不符合条件。

V 个跳一下,跳完后再一个一个跳就不用写二分了多好。

代码:

复制代码
#include<iostream>
#define int long long
using namespace std;
double a,b,c,k;
double x1,x2,y1,y2;
int gcd(int a,int b){
    if(b==0)return a;
    return gcd(b,a%b);
}
double check(int mid){return (-a*mid-c)/b;}
//-a*x%b==c
signed main(){
    cin>>a>>b>>c>>x1>>x2>>y1>>y2;
    //b/gcd(a,b);
    int l=x1,r=x2,mid;
    if((a>0)^(b>0))k=1;
    else k=-1;
    while(l<=r){
        mid=l+r>>1;
        double y=check(mid);
        if(y<y1){
            if(k==-1)r=mid-1;
            else l=mid+1;
        }else if(y>y2){
            if(k==-1)l=mid+1;
            else r=mid-1;
        }else r=mid-1;
    }
    double y=-a/b*(r+1)-c/b;
    if(y<y1||y>y2){
        cout<<0;
        return 0;
    }
    int ans=r+1,sum=0,d=(int)(b)/gcd(a,b);
     while((int)(-a*ans-c)%(int)b!=0)++ans;
    if(ans<x1)ans+=d;
    if(ans>x2){
        cout<<0;
        return 0;
    }
    sum=1;
    int t=(int)(b)/gcd(a,b);

    if(t<0)t=-t;
    while(ans+31622*t<=x2&&ans+31622*t>=x1&&check(ans+31622*t)>=y1&&check(ans+31622*t)<=y2){
        ans+=31622*t;
        sum+=31622;
    }
    while(ans+t<=x2&&ans+t>=x1&&check(ans+t)>=y1&&check(ans+t)<=y2){
        ans+=t;
        ++sum;
    }
    cout<<sum;
    return 0;
}
复制代码

 

posted @   Xy_top  阅读(59)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示