今日SGU 5.30

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\n",sz(nh));
    rep(i,0,sz(nh)) printf("%d %d\n",nh[i].fi + 1,nh[i].se + 1);
    printf("%d\n",sz(nv));
    rep(i,0,sz(nv)) printf("%d %d\n",nv[i].fi + 1,nv[i].se + 1);
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/chinacwj/p/9110151.html