F题解法各异,我分享一下我的解法吧。

采取贪心策略。第一个点肯定产生不了点对,我放在(0,0),接着

①如果分别向x方向和y方向拓展一个点。那么我们可以获得1个点对。

②如果把点放在(x,y),其中(x-1,y)和(x,y-1)都被点占据,那可以得到2个点对。这种情况要怎样才能满足呢?假设x,y方向拓展到的最大点分别是xm和ym,那么可以提供xm*ym次,放一个点增加2的机会。

x+y固定的情况下,x和y越接近,x*y越大。所以加到xm和ym的较小值上,这样能提供更多。

然后就贪心地一直添加点。要尽可能地多就得采取以上策略。如果k=1,那就采取操作1。否则能用操作2就用操作2。直到k等于0。

做完这些后,再看一下用了多少个点。如果点有剩,那就随便找个地方放。

using namespace std;
#include <bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
int main(){
	int n,k;
	cin>>n>>k;
	vector<PII>ans;
	ans.push_back({0,0});
	n--;
	queue<PII>q;
	int xm=0,ym=0;
	while(k){
		if(k==1||q.empty()){
			if(ym<xm){
				ans.push_back({0,++ym});k--;n--;
				for(int i=1;i<=xm;i++)q.push({i,ym});
			}
			else{
				ans.push_back({++xm,0});k--;n--;
				for(int i=1;i<=ym;i++)q.push({xm,i});
			}
		}
		else{
			ans.push_back(q.front());q.pop();
			k-=2;n--;
		}
	}
	if(n<0){
		cout<<"No"<<endl;return 0;
	}
	cout<<"Yes"<<endl;
	for(auto [x,y]:ans)cout<<x<<' '<<y<<endl;
	while(n--){
		cout<<1919810<<' '<<n*2<<endl;
	}
}