GYM103443E Composition with Large Red Plane, Yellow, Black, Gray, and Blue
阿新 • • 發佈:2022-03-09
官方題解好像是列出很多的線性方程,然後解出這個線性方程組。
這裡提供另一個做法。
我們考慮每一個方框的長寬都必然可以寫成兩個等差數列的 \(ax+b\) 形式,表示擴大 \(x\) 倍後的長度,其中 \(b\) 就是最小的合法長度,我們發現對於合併操作,其中相同的一個維度實際上就是讓這若干個等差數列求交,我們直接使用 \(\text{exCRT}\) 求解即可,而另一維度則根據前一維度進行調整即可。
#include<bits/stdc++.h> using namespace std; const int N=4e3+5,W=2e3+5,H=2e3+5; int n=0,w,h; vector<int> e[N]; int gcd(int a,int b){return b==0?a:gcd(b,a%b);} int exgcd(int a,int b,int &x,int &y){ if(b==0) return x=1,y=0,a; int _x,_y,tmp=exgcd(b,a%b,_x,_y); return x=_y,y=_x-a/b*_y,tmp; } struct Line{int a,b;}; Line operator + (Line f,Line g){ int x,y,tmp=exgcd(f.a,-g.a,x,y); if(!tmp){ if(g.b!=f.b) printf("Impossible\n"),exit(0); return f; } x*=(g.b-f.b)/tmp,y*=(g.b-f.b)/tmp,tmp=abs(tmp); if(x<0&&g.a){ int cnt=(0-x+g.a/tmp-1)/(g.a/tmp); x+=g.a/tmp*cnt,y+=f.a/tmp*cnt; } if(y<0&&f.a){ int cnt=(0-y+f.a/tmp-1)/(f.a/tmp); x+=g.a/tmp*cnt,y+=f.a/tmp*cnt; } if(f.a&&g.a){ int cnt=min(x/(g.a/tmp),y/(f.a/tmp)); x-=g.a/tmp*cnt,y-=f.a/tmp*cnt; } if(x<0||y<0) printf("Impossible\n"),exit(0); Line res=(Line){f.a*g.a/tmp,f.a*x+f.b}; if(res.a>1000) res.a=0; if(res.b>1000) printf("Impossible\n"),exit(0); return res; } struct Node{int dep,s;Line w,h;}tr[N]; int read(int dep){ int u=++n; scanf("%d",&tr[u].s),tr[u].dep=dep; if(!tr[u].s){ int w,h,tmp;scanf("%d%d",&w,&h),tmp=gcd(w,h),w/=tmp,h/=tmp; tr[u].w.a=w,tr[u].w.b=tr[u].w.a+2,tr[u].h.a=h,tr[u].h.b=tr[u].h.a+2; } else for(int i=1;i<=tr[u].s;++i) e[u].push_back(read(dep+1)); return u; } bool mp[W][H]; void dfs(int u){ for(auto v:e[u]) dfs(v); if(!tr[u].s); else if(tr[u].dep&1){ tr[u].w=(Line){1,0},tr[u].h=(Line){0,1-tr[u].s}; for(auto v:e[u]) tr[u].w=tr[u].w+tr[v].w; for(auto v:e[u]){ if(tr[v].w.a){ int tmp=tr[u].w.a/tr[v].w.a,TMP=(tr[u].w.b-tr[v].w.b)/tr[v].w.a; tr[u].h.a+=tr[v].h.a*tmp,tr[u].h.b+=tr[v].h.a*TMP+tr[v].h.b; } else{ int tmp=(tr[u].w.a==0),TMP=(tr[u].w.b-tr[v].w.b==0); tr[u].h.a+=tr[v].h.a*tmp,tr[u].h.b+=tr[v].h.a*TMP+tr[v].h.b; } } } else{ tr[u].h=(Line){1,0},tr[u].w=(Line){0,1-tr[u].s}; for(auto v:e[u]) tr[u].h=tr[u].h+tr[v].h; for(auto v:e[u]){ if(tr[v].h.a){ int tmp=tr[u].h.a/tr[v].h.a,TMP=(tr[u].h.b-tr[v].h.b)/tr[v].h.a; tr[u].w.a+=tr[v].w.a*tmp,tr[u].w.b+=tr[v].w.a*TMP+tr[v].w.b; } else{ int tmp=(tr[u].h.a==0),TMP=(tr[u].h.b-tr[v].h.b==0); tr[u].w.a+=tr[v].w.a*tmp,tr[u].w.b+=tr[v].w.a*TMP+tr[v].w.b; } } } } void DFS(int u,int l,int r,int L,int R){ // printf("%d %d %d %d %d\n",u,l,r,L,R); if(!tr[u].s){ for(int i=L;i<=R;++i) mp[i][l]=mp[i][r]=true; for(int j=l;j<=r;++j) mp[L][j]=mp[R][j]=true; return ; } else if(tr[u].dep&1){ int lst=L; for(auto v:e[u]){ if(tr[v].w.a){ int tmp=tr[u].w.a/tr[v].w.a,TMP=(tr[u].w.b-tr[v].w.b)/tr[v].w.a; tr[v].h.b=tr[v].h.a*TMP+tr[v].h.b,tr[v].h.a*=tmp; DFS(v,l,r,lst,lst+tr[v].h.b-1),lst+=tr[v].h.b-1; } else{ int tmp=(tr[u].w.a==0),TMP=(tr[u].w.b-tr[v].w.b==0); tr[v].h.b=tr[v].h.a*TMP+tr[v].h.b,tr[v].h.a*=tmp; DFS(v,l,r,lst,lst+tr[v].h.b-1),lst+=tr[v].h.b-1; } } } else{ int lst=l; for(auto v:e[u]){ if(tr[v].h.a){ int tmp=tr[u].h.a/tr[v].h.a,TMP=(tr[u].h.b-tr[v].h.b)/tr[v].h.a; tr[v].w.b=tr[v].w.a*TMP+tr[v].w.b,tr[v].w.a*=tmp; DFS(v,lst,lst+tr[v].w.b-1,L,R),lst+=tr[v].w.b-1; } else{ int tmp=(tr[u].h.a==0),TMP=(tr[u].h.b-tr[v].h.b==0); tr[v].w.b=tr[v].w.a*TMP+tr[v].w.b,tr[v].w.a*=tmp; DFS(v,lst,lst+tr[v].w.b-1,L,R),lst+=tr[v].w.b-1; } } } } int main(){ // freopen("1.in","r",stdin); cin>>w>>h,read(0),dfs(1); if(w<tr[1].w.b||h<tr[1].h.b) printf("Impossible\n"),exit(0); if(tr[1].w.a&&tr[1].h.a){ if((w-tr[1].w.b)%tr[1].w.a) printf("Impossible\n"),exit(0); if((h-tr[1].h.b)%tr[1].h.a) printf("Impossible\n"),exit(0); if((w-tr[1].w.b)/tr[1].w.a!=(h-tr[1].h.b)/tr[1].h.a) printf("Impossible\n"),exit(0); } else if(tr[1].w.a){ if((w-tr[1].w.b)%tr[1].w.a) printf("Impossible\n"),exit(0); if(h!=tr[1].h.b) printf("Impossible\n"),exit(0); if((w-tr[1].w.b)/tr[1].w.a!=0) printf("Impossible\n"),exit(0); } else if(tr[1].h.a){ if(w!=tr[1].w.b) printf("Impossible\n"),exit(0); if((h-tr[1].h.b)%tr[1].h.a) printf("Impossible\n"),exit(0); if((h-tr[1].h.b)/tr[1].h.a!=0) printf("Impossible\n"),exit(0); } else{ if(w!=tr[1].w.b) printf("Impossible\n"),exit(0); if(h!=tr[1].h.b) printf("Impossible\n"),exit(0); } tr[1].w.b=w,tr[1].h.b=h,DFS(1,1,w,1,h); for(int i=1;i<=h;++i){ for(int j=1;j<=w;++j) printf("%c",mp[i][j]?'*':' '); putchar('\n'); } return 0; }