dfs判断连通性的问题,5分钟秒杀
具体做法
n,m = map(int,input().split())
nums = []
for i in range(n):
nums.append(input())
f = [[False] * 110 for i in range(110)]
def dfs(x,y):
if f[x][y]:
return
f[x][y] = True
dx = [1,0,-1,0]
dy = [0,1,0,-1]
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0 <= nx < n and 0 <= ny < m and nums[nx][ny] == '#':
dfs(nx,ny)
cnt = 0
for i in range(n):
for j in range(m):
if nums[i][j] == '#' and f[i][j] == False:
dfs(i,j)
cnt += 1
print(cnt)
2. 子区域计数
我不知道为什么,我tle了四次,把用python写的tle的代码转换成c++,ac了???出题人难道还卡语言?
原本这题都看不懂题目,还是做完一三题后当时才十几分钟后做的,结果卡到九点才ac,心里很气
题目意思就是求有多少个子矩阵,能满足四条边的边框上没有#的符号
希望下次出题,在样例下方加一个样例说明,要不然真是考阅读理解了
放一份python的tle的代码
n,m = map(int,input().split())
nums = []
for i in range(n):
nums.append(input())
f = [[False] * 110 for i in range(110)]
cnt = 0
def check(x1,y1,x2,y2):
for i in range(x1,x2+1):
if nums[i][y1] == '#' or nums[i][y2] == '#':
return False
for i in range(y1,y2+1):
if nums[x1][i] == '#' or nums[x2][i] == '#':
return False
return True
res = []
for i in range(n):
for j in range(m):
if nums[i][j] == '#':
dx = [1,0,-1,0]
dy = [0,1,0,-1]
for k in range(4):
nx = i + dx[k]
ny = j + dy[k]
if 0 <= nx < n and 0 <= ny < m and nums[nx][ny] == '*':
f[nx][ny] = True
cnt = 0
for i in range(n):
for j in range(m):
if f[i][j] or nums[i][j] == '#':
continue
for k in range(i + 1,n):
for l in range(j + 1,m):
if nums[i][j] == '#' or f[k][l]:
continue
if check(i,j,k,l):
cnt += 1
print(cnt)
放一份C++的ac代码,就根据上面的代码翻译的hh
#includeusing namespace std; int n,m; bool f[110][110]; string a[110]; bool check(int x1,int y1,int x2,int y2){ for(int i = x1;i <= x2;i++){ if(a[i][y1] == '#' or a[i][y2] == '#'){ return false; } } for(int j = y1;j <= y2;j++){ if(a[x1][j] == '#' or a[x2][j] =='#'){ return false; } } return true; } int main() { cin >> n >> m; for(int i = 0;i < n ; i++){ cin >> a[i]; // scanf("%s",&a[i]); } for(int i = 0;i < n ;i ++){ for(int j = 0;j < m;j ++){ if(a[i][j] == '#'){ int dx[4] = {1,0,-1,0}; int dy[4] = {0,1,0,-1}; for(int k = 0 ; k< 4;k++){ int nx = i + dx[k]; int ny = j + dy[k]; if(0 <= nx && nx < n && 0 <= ny && ny < m && a[nx][ny] == '#'){ f[nx][ny] = true; } } } } // printf("n"); } long long cnt = 0; for(int i = 0;i < n;i ++){ for (int j = 0; j < m; j ++ ){ if( f[i][j] || a[i][j] == '#' ){ continue; } for (int k = i+1;k 3. 怀旧的思考挑战 简单模拟题
由于数据范围极小,可以直接四层循环暴力,看看哪四名选手的得分和等于n
n = int(input()) nums = [8,7,6,5,4,3,2,1] res = 0 for i in range(8): for j in range(i+1,8): for k in range(j+1,8): for l in range(k+1,8): if nums[i] + nums[j] + nums[k] + nums[l] == n: res += 1 if res != 0: print(res) else: print("NO")如果数据范围大的情况下,可以通过set优化掉最后一层循环
其次的优化解法,也可以通过logn的复杂度下进行二分查找



