SGU 190
题意:给你个n*n的矩形,然后上面有几个点不能放东西,然后问你能不能用1*2的矩形,把能放
东西的地方放满
收获:一开始想的是,dfs,然后感觉这样的话,代码很长,而且很容易超时,
看来题解发现,太妙了,奇偶染色,然后二分图匹配
然后就是要开始练打字了
#include<bits/stdc++.h> #define de(x) cout<<#x<<"="<<x<<endl; #define dd(x) cout<<#x<<"="<<x<<" "; #define rep(i,a,b) for(int i=a;i<(b);++i) #define repd(i,a,b) for(int i=a;i>=(b);--i) #define repp(i,a,b,t) for(int i=a;i<(b);i+=t) #define ll long long #define mt(a,b) memset(a,b,sizeof(a)) #define fi first #define se second #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define pii pair<int,int> #define pdd pair<double,double> #define pdi pair<double,int> #define mp(u,v) make_pair(u,v) #define sz(a) (int)a.size() #define ull unsigned long long #define ll long long #define pb push_back #define PI acos(-1.0) #define qc std::ios::sync_with_stdio(false) #define db double #define all(a) a.begin(),a.end() const int mod = 1e9+7; const int maxn = 2e3+6; const double eps = 1e-6; using namespace std; bool eq(const db &a, const db &b) { return fabs(a - b) < eps; } bool ls(const db &a, const db &b) { return a + eps < b; } bool le(const db &a, const db &b) { return eq(a, b) || ls(a, b); } ll gcd(ll a,ll b) { return a==0?b:gcd(b%a,a); }; ll lcm(ll a,ll b) { return a/gcd(a,b)*b; } ll kpow(ll a,ll b) {ll res=1; if(b<0) return 1; for(;b;b>>=1){if(b&1)res=res*a;a=a*a;}return res;} ll read(){ ll x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,p; int m[52][52] = {0}; int dx[] = {0,1,0,-1}; int dy[] = {1,0,-1,0}; int vis[maxn]; int pi[maxn]; vector<pii> nh,nv; vector<int> G[maxn]; bool ep(int u){ rep(i,0,sz(G[u])){ int v = G[u][i]; if(vis[v]) continue; vis[v] = true; if(pi[v]==-1||ep(pi[v])) { pi[v] = u; return true; } } return false; } bool ok(int x,int y){ if(x<0||x>=n) return false; if(y<0||y>=n) return false; return true; } int main(){ mt(pi,-1); scanf("%d%d",&n,&p); rep(i,0,p) { int x,y; scanf("%d%d",&x,&y), m[--x][--y] = 1; } int d = n*n - p; if(d&1) return puts("No"),0; rep(x,0,n) rep(y,0,n) if(!m[x][y]&&((x+y)&1)) { rep(k,0,4){ int nx = x + dx[k], ny = y + dy[k]; if(!ok(nx,ny)) continue; if(!m[nx][ny]) { // dd(x)dd(y)dd(nx)de(ny) G[x*n+y].pb(nx*n+ny),G[nx*n+ny].pb(x*n+y); } } } int ans = 0; rep(i,0,n) rep(j,0,n) { if(!m[i][j]&&((i+j)&1)) { mt(vis,false); if(ep(i*n+j)) ans++; } } if(ans * 2 != d) return puts("No"),0; puts("Yes"); rep(i,0,n) rep(j,0,n){ if(!m[i][j] && !((i+j)&1)){ int u = i * n + j; if(pi[u] - u == n) nh.pb(mp(i,j)); if(pi[u] - u == 1) nv.pb(mp(i,j)); if(u - pi[u] == n) nh.pb(mp(pi[u]/n,pi[u]%n)); if(u - pi[u] == 1) nv.pb(mp(pi[u]/n,pi[u]%n)); } } printf("%d ",sz(nh)); rep(i,0,sz(nh)) printf("%d %d ",nh[i].fi + 1,nh[i].se + 1); printf("%d ",sz(nv)); rep(i,0,sz(nv)) printf("%d %d ",nv[i].fi + 1,nv[i].se + 1); return 0; }