zoukankan      html  css  js  c++  java
  • [Cometoj#4 C]方块切割_质因数分解_贪心

    方块切割

    题目链接https://cometoj.com/contest/39/problem/C?problem_id=1583

    数据范围:略。


    题解

    首先,如果我们知道了多少道在行上,多少刀在列上,应该怎么办?

    不难发现行和列是独立的,只需要分别保证各自均分了网格即可。

    那么怎么切呢?只需要顺次枚举,能切就切即可。

    至于怎么知道行和列各自切多少刀?

    枚举呗

    代码

    #include <bits/stdc++.h>
    
    #define N 1010 
    
    using namespace std;
    
    int r[N], c[N];
    char a[N][N];
    int s[N][N];
    int ans[2 * N];
    int x[N], y[N];
    int n, m, k;
    
    int main() {
    	int T;
    	scanf("%d", &T);
    	while (T--) {
    		scanf("%d%d%d", &n, &m, &k);
    		for (int i = 1; i <= n; i++) {
    			r[i] = 0;
    		}
    		for (int i = 1; i <= m; i++) {
    			c[i] = 0;
    		}
    		int sum = 0;
    		for (int i = 1; i <= n; i++) {
    			scanf("%s", a[i] + 1);
    			for (int j = 1; j <= m; j++) {
    				if (a[i][j] == '0') {
    					r[i]++;
    					c[j]++;
    					sum++;
    				}
    			}
    		}
    		for (int i = 1; i <= n; i++) {
    			for (int j = 1; j <= m; j++) {
    				s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
    				s[i][j] += a[i][j] == '0';
    			}
    		}
    		for (int i = 1; i <= k; i++) {
    			ans[i] = n + m - 1;
    		}
    		if (sum == 0) {
    			for (int i = 1; i < k; i++) {
    				printf("%d ", i);
    			}
    			printf("%d", k);
    			printf("
    ");
    			continue;
    		}
    		for (int l = k; l >= 0; l--) {
    			if (sum % ((l + 1) * (k - l + 1))) continue;
    			int br = sum / (l + 1);
    			int bc = sum / (k - l + 1);
    			int b = sum / (l + 1) / (k - l + 1);
    			bool f = 1;
    			int cur = 0;
    			int X = 0;
    			for (int i = 1; i <= n; i++) {
    				cur += r[i];
    				if (cur == br) {
    					x[++X] = i;
    					cur = 0;
    				}
    				if (cur > br) f = 0;
    			}
    			cur = 0;
    			int Y = 0;
    			for (int i = 1; i <= m; i++) {
    				cur += c[i];
    				if (cur == bc) {
    					y[++Y] = i;
    					cur = 0;
    				}
    				if (cur > bc) f = 0;
    			}
    			for (int i = 1; i <= X; i++) {
    				for (int j = 1; j <= Y; j++) {
    					if (s[x[i]][y[j]] - s[x[i - 1]][y[j]] - s[x[i]][y[j - 1]] + s[x[i - 1]][y[j - 1]] != b) f = 0;
    				}
    			}
    			if (!f) continue;
    			for (int i = 1; i < X; i++) ans[i] = x[i];
    			for (int i = 1; i < Y; i++) ans[l + i] = y[i] + n - 1;
    			break;
    		}
    		if (ans[1] == n + m - 1) {
    			printf("Impossible
    ");
    		}
    		else {
    			for (int i = 1; i < k; i++) {
    				printf("%d ", ans[i]);
    			}
    			printf("%d", ans[k]);
    			printf("
    ");
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    我所理解的MVC
    关于开发文化的思考
    使用纯C语言开始win32 sdk编程
    谈谈编译原理和其在WEB开发中的应用1
    最简单的win32程序(c语言实现)
    关于Javascript的一些心得与记忆
    Cvv.WebUtility 我的MVC框架介绍
    发现了个不错的图片网站
    轻轻松松做开发--目前网站开发的流行原素
    我的模板分析引擎类PHP的.net开发方法标签设计篇
  • 原文地址:https://www.cnblogs.com/ShuraK/p/11726716.html
Copyright © 2011-2022 走看看