zoukankan      html  css  js  c++  java
  • CodeForces

    Description

    (n imes m) 的棋盘,用 (K) 种颜色给每个格子染色,并给出每两个相邻格子间的要求(相同或不同),构造一种方案使得至少满足其中 (cfrac{3}{4}) 的要求。

    (n,mle 1000)

    Solution

    这出题人怎么不出 5000

    我会构造.jpg

    结论是无解的情况存在且仅存在于 (K=1)(N) 的数量大于 (cfrac{tot}{4}) 时。别的情况一定可以用两个颜色构造出解。接下来是构造方法和证明。

    假定竖着的要求数量大于横着的(不是的话可以转一下),那先不考虑横着的要求,那对于每一列一定可以用至多两种颜色构造出完全符合该列所有要求的方案。于是这样就满足了总要求的 (cfrac{1}{2})

    然后考虑横着的要求。枚举每一列,若当前列与上一列间的横着的要求中,不成立的大于 (cfrac{1}{2}) ,那就把当前列全部取反。于是最后横要求也能满足 (cfrac{1}{2}) ,总共就能满足 (cfrac 3 4)

    复杂度 (O(nm))

    #include<bits/stdc++.h>
    using namespace std;
    
    template <class T> void read(T &x) {
    	x = 0; bool flag = 0; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) flag |= (ch == '-');
    	for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48; flag ? (x = -x) : 0;
    }
    
    #define N 1010
    #define rep(i, a, b) for (int i = (a); i <= (b); i++)
    
    int n, m, K, r1, r2, c1, c2, ans[N][N];
    bool r[N][N], c[N][N], tmp[N][N];
    
    int main() {
    	read(n), read(m), read(K);
    	r2 = m, c2 = m - 1;
    	int nCnt = 0, tot = 0;
    	rep(i, 1, 2 * n - 1) {
    		int x = (i & 1) ? m - 1 : m;
    		(x == m ? r1 : c1)++;
    		rep(j, 1, x) {
    			char ch = getchar(); for (; ch != 'E' && ch != 'N'; ch = getchar());
    			nCnt += (ch == 'N'), tot++;
    			(x == m - 1 ? c[c1][j] : r[r1][j]) = (ch == 'E');
    		}
    	}
    
    	if (K == 1) {
    		if (nCnt <= tot / 4) {
    			puts("YES");
    			rep(i, 1, n) {
    				rep(j, 1, m) printf("1 ");
    				puts("");
    			}
    		}
    		else puts("NO");
    		return 0;
    	}
    
    	bool swapTag = 0;
    	if (r1 * r2 < c1 * c2) {
    		swapTag = 1;
    		memcpy(tmp, r, sizeof r), memset(r, 0, sizeof r);
    		rep(i, 1, c1) rep(j, 1, c2) r[j][i] = c[i][j];
    		memset(c, 0, sizeof c);
    		rep(i, 1, r1) rep(j, 1, r2) c[j][i] = tmp[i][j];
    		swap(n, m), r1 = n - 1, r2 = m, c1 = n, c2 = m - 1;
    	}
    
    	rep(j, 1, m) rep(i, 2, n) ans[i][j] = ans[i - 1][j] ^ (r[i - 1][j] ? 0 : 1);
    	rep(j, 2, m) {
    		int cnt = 0;
    		rep(i, 1, n) cnt += (c[i][j - 1] != (ans[i][j] == ans[i][j - 1]));
    		if (cnt > n / 2) rep(i, 1, n) ans[i][j] = ans[i][j] ^ 1;
    	}
    
    	puts("YES");
    	if (swapTag) {
    		rep(i, 1, m) {
    			rep(j, 1, n) printf("%d ", ans[j][i] + 1);
    			puts("");
    		}
    	}
    	else {
    		rep(i, 1, n) {
    			rep(j, 1, m) printf("%d ", ans[i][j] + 1);
    			puts("");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Docker 容器间的单向连接
    使用 mysql 的 Docker 镜像
    Dockerfile 自动制作 Docker 镜像(三)—— 镜像的分层与 Dockerfile 的优化
    Dockerfile 自动制作 Docker 镜像(一)—— 基本命令
    在 Docker 的 CentOS7 镜像 中安装 mysql
    手动制作Docker镜像
    Docker容器基本命令注意点
    Linux基础15-Linux库函数
    Linux基础14-makefile
    Linux基础13-GDB调试
  • 原文地址:https://www.cnblogs.com/aziint/p/9493858.html
Copyright © 2011-2022 走看看