第一行输入三个正整数
。
接下来
行每行输入一个长度为
的字符串,其中第
行第
个字母为
。
其中
为所有小写英文字母'a'-'z'的集合。
输出一个正整数表示包含至少种不同字母的方形子矩阵的边长,如果不存在该子方阵,输出
。
4 4 3 aabc aaaa axaz abcd
2
不存在边长为
的方形子矩阵包含至少
种不同的字母。
如图,存在边长为
的方形子矩阵包含至少
种不同的字母:
2 2 5 ab cd
-1
显然矩阵总共只有种字符,因此答案为
。
import math n,m,k = input().split(' ') n,m,k = int(n),int(m),int(k) a = [] for i in range(n): a.append(list(input())) # 从矩阵a中找以a[i][j]为首的,边长为r的正方形中唯一字母的个数(用set的长度) def count_sub_mat(a,i,j,r): return len(set([a[x][y] for x in range(i,i+r) for y in range(j,j+r)])) start_r = int(math.ceil(math.sqrt(k))) # 开始搜索的正方形边长 if start_r>m*n: print(-1) else: max_r = min(m,n) flag = False for r in range(start_r, max_r): if flag: break for i in range(n-r+1): if flag: break for j in range(m-r+1): if flag: break if(count_sub_mat(a,i,j,r)>=k): print(r) flag = True
import java.io.*; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] params = br.readLine().split(" "); int n = Integer.parseInt(params[0]); int m = Integer.parseInt(params[1]); int k = Integer.parseInt(params[2]); char[][] matrix = new char[n][]; for(int i = 0; i < n; i++){ matrix[i] = br.readLine().toCharArray(); } int resEdge = -1; for(int edge = Math.min(n, m); edge >= (int)Math.ceil(Math.sqrt(k)); edge--){ if(convolution(matrix, edge, k)){ resEdge = edge; }else{ break; } } System.out.println(resEdge); } private static boolean convolution(char[][] matrix, int edge, int lb){ // 从左上角初始化计数器 int[] counter = new int[26]; int nunique = 0; for(int i = 0; i < edge; i++){ for(int j = 0; j < edge; j++){ if(counter[matrix[i][j] - 'a'] == 0){ nunique++; } counter[matrix[i][j] - 'a']++; } } if(nunique >= lb){ return true; } // 之字形滑动窗口 boolean left2right = true; // 先从左往右滑动 for(int i = 0; i <= matrix.length - edge; i++){ if(left2right){ for(int j = 0; j <= matrix[0].length - edge; j++){ if(j > 0){ for(int r = i; r < i + edge; r++){ counter[matrix[r][j - 1] - 'a']--; if(counter[matrix[r][j - 1] - 'a'] == 0){ nunique--; } counter[matrix[r][j + edge - 1] - 'a']++; if(counter[matrix[r][j + edge - 1] - 'a'] == 1){ nunique++; } } } if(nunique >= lb){ return true; } } // 构建下一行的初始窗口 if(i + edge < matrix.length){ for(int k = matrix[0].length - edge; k < matrix[0].length; k++){ counter[matrix[i][k] - 'a']--; if(counter[matrix[i][k] - 'a'] == 0){ nunique--; } counter[matrix[i + edge][k] - 'a']++; if(counter[matrix[i + edge][k] - 'a'] == 1){ nunique++; } } } }else{ for(int j = matrix[0].length - edge; j >= 0; j--){ if(j < matrix[0].length - edge){ for(int k = i; k < i + edge; k++){ counter[matrix[k][j + edge] - 'a']--; if(counter[matrix[k][j + edge] - 'a'] == 0){ nunique--; } counter[matrix[k][j] - 'a']++; if(counter[matrix[k][j] - 'a'] == 1){ nunique++; } } } if(nunique >= lb){ return true; } } if(i + edge < matrix.length){ for(int k = 0; k < edge; k++){ counter[matrix[i][k] - 'a']--; if(counter[matrix[i][k] - 'a'] == 0){ nunique--; } counter[matrix[i + edge][k] - 'a']++; if(counter[matrix[i + edge][k] - 'a'] == 1){ nunique++; } } } } left2right = !left2right; } return false; } }
import java.util.*; public class Main { private static int[][] sum; private static int cur = 1; private static int n, m, k; private static int maxLength; public static void main(String[] args) { Scanner in = new Scanner(System.in); n = in.nextInt(); m = in.nextInt(); k = in.nextInt(); String xx = in.nextLine(); sum = new int[n][m]; for (int i = 0; i < n; i ++) { String s = in.nextLine(); int j = 0; for (char c : s.toCharArray()) { sum[i][j++] = 1 << (c - 'a'); } } // for (int i = 0; i < n; i ++) System.out.println(Arrays.toString(sum[i])); maxLength = Math.min(n, m); if (maxLength * maxLength < k) { System.out.println(-1); } else if (k == 1) { System.out.println(1); } else { if (find()) System.out.println(cur); else System.out.println(-1); } // System.out.println(sum[0][0]); } public static boolean find() { for (int l = 2; l <= maxLength; l ++) { for (int i = 0; i < n - l + 1; i ++) { for (int j = 0; j < m - l + 1; j ++) { sum[i][j] = sum[i][j] | sum[i+1][j] | sum[i][j+1] | sum[i+1][j+1]; } } if (l * l < k) continue; for (int i = 0; i < n - l + 1; i ++) { for (int j = 0; j < m - l + 1; j ++) { int t = sum[i][j]; int cnt = 0; while (t > 0) { if ((t & 1) == 1) cnt ++; t >>= 1; } if (cnt >= k) { cur = l; return true; } } } } return false; } }
from math import sqrt class Array: """实现__getitem__,支持序列获取元素、Slice等特性""" def __init__(self, lst): self.__coll = lst def __repr__(self): """显示列表""" return '{!r}'.format(self.__coll) def __getitem__(self, key): """获取元素""" slice1, slice2 = key row1 = slice1.start row2 = slice1.stop col1 = slice2.start col2 = slice2.stop return [self.__coll[r][col1:col2] for r in range(row1, row2)] while True: try: nmk = input().split(' ') n = int(nmk[0]) m = int(nmk[1]) k = int(nmk[2]) if n * m < k: print(-1) break A = [] for i in range(n): A.append(list(map(str, input().strip()))) A = Array(A) S = 0 # 字母的种类 length = -1 for l in range(int(sqrt(k)) + 1, min(n, m)): # 矩阵边长 for i in range(min(n, m)-int(sqrt(k))): for j in range(min(n, m)-int(sqrt(k))): As = A[i:i+l, j:j+l] # 取边长为l的正方形子矩阵,并降维去重 if len(set(sum(As, []))) > S: S = len(set(sum(As, []))) if S >= k: length = l break break break print(length) except: break暴力搜索,但只能通过前13个用例
不知道怎么优化了,只能通过7组用例,其他的超时。
#include #include #include #include using namespace std; int res,resLen; void dfs(vector& square, int i, int j, int length,int& k){ if(resLen==k) return; if(j+length>square[0].length()&&i+length<square.size()){ i++; j=0; }else if(j+length > square[0].length()||i+length>square.size()) return; set st; for(int row = i;row < i+length;row++){ for(int col = j;col<j+length;col++){ st.insert(square[row][col]); } } if(st.size()==k){ res = length; resLen = k; } dfs(square, i, j+1, length, k); } int main(){ int n,m,k; cin>>n>>m>>k; vector square(n); for(int i = 0; i < n; i++){ cin>>square[i]; } int length = n>m?m:n; res = length+1; for(int i = 2; i <= length;i++){ dfs(square, 0, 0, i, k); if(res<length+1) break; } if(res==length+1) res = -1; cout<<res<<endl; }
class Solution: def check(self, n, m, s, k, pre): # s表示边长 # pre[i][j][t]表示以array[i][j]为右下角元素,array[0][0]为左上角元素正方形内 字母t出现的次数 for i in range(1, n+1): for j in range(1, m+1): if i + s -1 > n&nbs***bsp;j + s - 1 > m: continue count = 0 for t in range(26): if pre[i+s-1][j+s-1][t]-pre[i+s-1][j-1][t]-pre[i-1][j+s-1][t]+pre[i-1][j-1][t]>=1: count += 1 if count >= k: return True return False def minSideLength(self, array, n, m, k): import math pre = [[[0]*26 for _ in range(m+1)] for _ in range(n+1)] for i in range(1, n+1): for j in range(1, m+1): for t in range(26): pre[i][j][t] = pre[i-1][j][t] + pre[i][j-1][t] - pre[i-1][j-1][t] t = ord(array[i-1][j-1]) - ord("a") pre[i][j][t] += 1 minS, maxS = int(math.sqrt(k)), min(n, m) res = -1 while minS <= maxS: midS = (minS + maxS)>>1 if self.check(n, m, midS, k, pre): maxS = midS -1 res = midS else: minS = midS + 1 return res if __name__ == "__main__": [n, m, k] = list(map(int, input().strip().split())) array = [] for i in range(n): string = input() array.append(string) s = Solution() res = s.minSideLength(array, n, m, k) print(res)请问Python 3这样写有问题吗?老是显示超时 是语言的问题吗