竞赛讨论区 > 求助F过72%
头像
牛客358928195号
编辑于 03-24 15:55 北京
+ 关注

求助F过72%

#include<bits/stdc++.h>
using namespace std;

int main () {
    int n,k;
    cin>>n>>k;
    if(n==1 || (n==2 && k>1) || (n>2 && k > 1+(n-2)/2*2+(n-1)/2)) {
        cout<<"No"<<endl;
        return 0;
    }
    cout<<"Yes"<<endl;
    int x=0,y=0,ck=0,tx=0,ty=4,cn=1,p=1;
    cout<<x<<' '<<y<<endl;
    y++;
    cout<<x<<' '<<y<<endl;
    ck++;
    cn++;
    while(ck+2<=k && cn<n) {
        if(p==1) {
            x++;
            ck++;
            cn++;
            p^=1;
        } else {
            y^=1;
            ck+=2;
            cn++;
            p^=1;
        }
        cout<<x<<' '<<y<<endl;
    }
     if(ck+1==k) {
            x++;
            ck++;
            cn++;
            cout<<x<<' '<<y<<endl;
     }
    if(ck==k && cn<n) {
            while(cn++<n) {
                cout<<tx<<' '<<ty<<endl;
                tx+=2;
            }
    }
}

思路是这样,考虑k大于0,所以先按两个点。然后贪心构造最大,在y=0,y=1之间按蛇形排列。停下来时,差1或者差0,差一补一条。不差后,把剩下的点放远端。

对于一开始判断可不可以,是n=1不可能,n=2,k只能为1,n>2看奇偶个数找出上界。感觉没问题但是只能过72%。

麻烦大家了。

找到问题了,首先贪心构造不对,应该是螺旋紧密排列会形成最大值,所以原来的两条链会出错。

#include<bits/stdc++.h>
using namespace std;

vector<pair<int,int>> dir={
    {0,1},{1,0},{0,-1},{-1,0}
};
vector<pair<int,int>> ans;

int main () {
    int n,k;
    cin>>n>>k;
    if(n==1) {
        cout<<"No"<<endl;
        return 0;
    }
    int x=0,y=0,ck=0,tx=0,ty=-1e9,cn=1;
    ans.push_back({x,y});
    int temp=1,d=0,cnt=0;
    while(ck<k && cn<n) {
        cnt++;
        auto [dx,dy]=dir[d];
        for(int i=0;i<temp && cn<n &&ck<k;i++) {
            int next;
            if(i==temp-1) next=1;
            else next=2;
            if(ck+next>k) {
                auto [ddx,ddy]=dir[(d+3)%4];
                ck++;
                cn++;
                x+=ddx;
                y+=ddy;
                ans.push_back({x,y});
            }
            else {
                x+=dx;
                y+=dy;
                ck+=next;
                ans.push_back({x,y});
                cn++;
            }
        }
        if(cnt==2) temp++;
        cnt%=2;
        d++;
        d%=4;
    }
    if(ck<k) {
        cout<<"No"<<endl;
    } else {
        cout<<"Yes"<<endl;
        while(cn++<n) {
            tx+=2;
            ans.push_back({tx,ty});
        }
        for(auto [a,b]:ans) cout<<a<<' '<<b<<endl;
    }
}

模拟思路是确立方向顺序,发现沿某方向放x个时,第x个贡献1,其他贡献0(如果合理的话),所以不断加入。中间溢出时一定是+2,这时沿上一次的方向就变成+1了。所以最后检查ck够不够,不够就是no,yes的话就输出按时。

全部评论

(0) 回帖
加载中...
话题 回帖

等你来战

查看全部

热门推荐