AT_arc139_c

会正解做法之后还以为 10 10 答案是 3737……

钦定 nmn\le m,从 3x+y3x+yx+3yx+3y 的匹配的角度考虑。考虑对于一对 x,yx,y,我们保持 3x+y3x+y 不变,xx1x\to x-1x+3yx+3y 如何变化。发现 x+3y(x1)+3(y+3)=x+3y+8x+3y\to (x-1)+3(y+3)=x+3y+8。于是对于一个 3x+y=p3x+y=p,符合条件的 x+3y=q=8k+zx+3y=q=8k+zzz 为定值且 kk 为一个区间。

再进一步,设 k[l,r]k\in[l,r],容易发现对于 3x+y=p83x'+y'=p-8zz 不变,但是 l,rl,r 变化。具体地 ll,rrl'\le l,r'\le r。则贪心地想,从小到大枚举 pp,每个 3x+y3x+y 都选择最小的满足条件的 kk(即选择能匹配的最小的 x+3yx+3y),这样一定是不优的。开个数组对每个 zz 记录当前已经选了的最大的 kk,从前往后扫 pp,从 k+1k+1 开始判断是否可行。

由于 pp,ll,rr\forall p'\le p,l'\le l,r'\le r 所以这个贪心是正确的。

code:

int n,m;
int b[12]={0,0,0,0,4,7,10,5,8,11,6,9};
void Yorushika(){
	scanf("%d%d",&n,&m);
	bool fl=0;
	if(n<m){
		swap(n,m);
		fl=1;
	}
	vector<pii> ans;
	rep(i,4,m*3+n){
		int p=(i-4)%8+4;
		int &j=b[p];
		int x=((i+j)/4-(i-j)/2)/2,y=(i-x)/3;
		while(x<1||y>m){
			j+=8;
			x=((i+j)/4-(i-j)/2)/2,y=(i-x)/3;
		}
		if(x<=n&&y>=1){
			if(fl){
				swap(x,y);
			}
			ans.eb(x,y);
		}
		j+=8;
	}
	printf("%d\n",ans.size());
	for(auto [i,j]:ans){
		printf("%d %d\n",i,j);
	}
}
signed main(){
	int t=1;
	//	scanf("%d",&t);
	while(t--)
		Yorushika();
}