零点

  • 题目链接:零点
  • 如果没有权限看题,请看下图

  • 题目思路:就是模拟了,根据题意模拟即可,具体解释见代码。
  • 附件:关于求y=kx+b的相关公式
  • 代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define gc getchar()
    #define ll long long
    #define Maxn 700010
    #define Maxx 300000
    using namespace std;
    ll sc() {
    ll xx=0,ff=1; char cch=gc;
    while(cch<'0'|| cch>'9') {
    if(cch=='-') ff=-ff; cch=gc;
    }
    while(cch>='0'&& cch<='9') {
    xx=(xx<<1)+(xx<<3)+(cch^48); cch=gc;
    }
    return xx*ff;
    }
    ll n,cnt;
    ll lax,lay,x,y;
    ll ans[Maxn];
    int main() {
    n=sc();
    lax=sc(); lay=sc(); //lax lay 为上一个点的横纵坐标
    if(!lay)
    ans[++cnt]=lax; //如果第一个点的纵坐标为0,则lax为一个零点
    for(ll i=2; i<=n; i++) {
    x=sc(); y=sc();
    if(i==2&& ((lay>0&&y>lay&&(y-lay)*(x-lax)>0)|| (lay<0&&y<lay&&(y-lay)*(x-lax)<0))) //处理射线,当射线满足形似'/'或'\'时
    if((lay*(x-lax)%(y-lay))==0) { //零点为整点
    ans[++cnt]=lax-lay*(x-lax)/(y-lay); //由公式求出零点
    if(cnt>Maxx) {
    printf("-1\n");
    return 0;
    }
    }
    if(lay==0&&y==0) { //如果当前点和上一点在x轴上
    if(i==2||i==n) { //如果在射线上,那么数量肯定会超过3e5
    printf("-1\n");
    return 0;
    }
    for(ll j=lax+1; j<=x; j++) { //否则就把它们之间的零点存入
    ans[++cnt]=j;
    if(cnt>Maxx) {
    printf("-1\n");
    return 0;
    }
    }
    }
    else if(lay!=0&&y==0) { //如果上一点不在x轴上,而当前点在x轴上,存入
    ans[++cnt]=x;
    if(cnt>Maxx) {
    printf("-1\n");
    return 0;
    }
    }
    else if(lay*y<0) { //如果前后两点在x轴两侧
    if((lay*(x-lax)%(y-lay))==0) { //同上
    ans[++cnt]=lax-lay*(x-lax)/(y-lay);
    if(cnt>Maxx) {
    printf("-1\n");
    return 0;
    }
    }
    }
    if(i==n&& ((y<0&&y>lay&&(y-lay)*(x-lax)>0)|| (y>0&&y<lay&&(y-lay)*(x-lax)<0))) //处理第二条射线,思路和第一条射线基本一样,但做法不同
    if((lay*(x-lax)%(y-lay))==0) {
    ans[++cnt]=lax-lay*(x-lax)/(y-lay);
    if(cnt>Maxx) {
    printf("-1\n");
    return 0;
    }
    }
    lax=x; lay=y; //更新上一个点坐标
    }
    printf("%lld\n",cnt); //输出
    for(ll i=1; i<=cnt; i++)
    printf("%lld ",ans[i]);
    return 0;
    }
rp++