#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) 回帖