noiopenjudge07:矩阵归零消减序列和 模拟

本文介绍了一个用于解决NOIOPENJUDGE中矩阵归零问题的算法实现。该算法通过模拟的方式逐步减少矩阵元素值,直至所有元素归零。过程中涉及到寻找每行最小值、每列最小值,并据此更新矩阵。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

noiopenjudge07:矩阵归零消减序列和

sx模拟

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;

#define MAXN (120)
int maps[MAXN][MAXN];
int hang[MAXN], lie[MAXN];

int main()
{
    int n;
    cin >> n;
    for(int i = 1; i <= n; ++ i)
        for(int j = 1; j <= n; ++ j)
            scanf("%d", &maps[i][j]);
    #define INF (1e9)
    printf("%d\n", maps[2][2]);
    while(n > 1)
    {
        fill(hang+1, hang+n+1, 1e9);
        fill(lie+1, lie+n+1, 1e9);
        for(int i = 1; i <= n; ++ i)
            for(int j = 1; j <= n; ++ j)
                hang[i] = min(hang[i], maps[i][j]);
        for(int i = 1; i <= n; ++ i)
            for(int j = 1; j <= n; ++ j)
                maps[i][j] -= hang[i];
        for(int i = 1; i <= n; ++ i)
            for(int j = 1; j <= n; ++ j)
                lie[j] = min(lie[j], maps[i][j]);
        for(int i = 1; i <= n; ++ i)
            for(int j = 1; j <= n; ++ j)
                maps[i][j] -= lie[j];

        for(int i = 3; i <= n; ++ i)
            for(int j = 1; j <= n; ++ j)
                maps[i-1][j] = maps[i][j];
        for(int i = 1; i <= n; ++ i)
            for(int j = 3; j <= n; ++ j)
                maps[i][j-1] = maps[i][j];
        printf("%d\n", maps[2][2]);
        -- n;
    }
    return 0;
}
### 关于NOI 1.8题库中的C语言题目解答 #### 肿瘤面积计算 对于肿瘤面积的求解,涉及到连通块问题以及二维数组的应用。通过给定的一个字符矩阵表示图像,其中'@'代表癌细胞位置,其他符号代表正常组织部分。为了找到所有癌细胞组成的区域大小,可以采用深度优先搜索(DFS)算法来遍历相连的癌细胞群落并统计其数量。 ```c #include <stdio.h> #define MAXN 1005 char map[MAXN][MAXN]; int n, m; void dfs(int x, int y){ if(x<0 || x>=n || y<0 || y>=m || map[x][y]!='@') return; map[x][y] = '*'; //标记已访问 //八个方向扩散 dfs(x-1,y);dfs(x+1,y); dfs(x,y-1);dfs(x,y+1); dfs(x-1,y-1);dfs(x-1,y+1); dfs(x+1,y-1);dfs(x+1,y+1); } int main(){ while(scanf("%d%d",&n,&m)!=EOF && (n||m)){ for(int i=0;i<n;++i) scanf("%s",map[i]); int cnt = 0; for(int i=0;i<n;++i) for(int j=0;j<m;++j) if(map[i][j]=='@'){ ++cnt;dfs(i,j); } printf("%d\n",cnt); } } ``` 此程序实现了对输入数据中每一块独立存在的癌变区进行计数的功能[^1]。 #### 二维数组回形遍历实现 针对二维数组按照特定路径顺序读取元素的需求,在这里介绍一种基于模拟的方法——即让一个虚拟指针沿着指定路线移动直至覆盖全部格子。具体做法是从左上角出发沿顺时针螺旋线逐步向内收缩边界直到完成整个表格扫描工作。 ```c #include<stdio.h> const int maxn = 25; int a[maxn][maxn], b[maxn*maxn]; int main() { int n; scanf("%d", &n); for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) scanf("%d", &a[i][j]); int top = 0, bottom = n - 1, left = 0, right = n - 1, index = 0; while (top <= bottom && left <= right) { for (int col = left; col <= right; ++col) b[index++] = a[top][col];++top; for (int row = top; row <= bottom; ++row) b[index++] = a[row][right];--right; if (top <= bottom) for (int col = right; col >= left; --col) b[index++] = a[bottom][col];--bottom; if (left <= right) for (int row = bottom; row >= top; --row) b[index++] = a[row][left];++left; } for (int i = 0; i < n * n; ++i) printf("%d%c", b[i], " \n"[i==n*n-1]); } ``` 上述代码片段展示了如何利用循环控制结构配合条件判断语句达成预期效果[^2]。 #### 矩阵归零消减序列处理 当面对需要多次操作同一位置数值的情况时,可以通过预先记录下每次变化后的状态来进行最终结果输出。本案例中提到的操作是指不断选取当前剩余最大值所在行列并将这些行与列上的其它非目标单元置零的过程;值得注意的是,尽管经过多轮迭代更新,仍需保持原始状态下某些固定坐标处的数据不变以便后续查询使用。 ```c #include <bits/stdc++.h> using namespace std; typedef pair<int,int> PII; PII pos[105]; bool vis[105][105]={false}; int mat[105][105],ans[105]; int main(){ memset(mat,-1,sizeof(mat)); int N,M,Q,x,y,val,maxx=-99999999,minn=99999999,kase=0; char op[5]; cin>>M>>Q; vector<pair<int,pair<int,int>>> vec; for(int i=1;i<=M;i++){ for(int j=1;j<=M;j++)cin>>mat[i][j]; } cout<<mat[2][2]<<endl; for(int qqqq=1;qqqq<Q;qqqq++){ cin>>(op+1)>>val; if(op[1]=='R') for(int i=1;i<=M;i++) if(!vis[val][i])vec.push_back({mat[val][i],{val,i}}); else for(int i=1;i<=M;i++) if(!vis[i][val])vec.push_back({mat[i][val],{i,val}}); sort(vec.begin(),vec.end()); reverse(vec.begin(),vec.end()); ans[++kase]=vec.front().first; maxx=max(maxx,vec.front().first); minn=min(minn,vec.front().first); vis[pos[kase].second.first][pos[kase].second.second]=true; vec.clear(); } for(int i=1;i<=kase;i++)cout<<ans[i]<<" "; puts(""); cout<<minn<<" "<<maxx<<"\n"; cout<<mat[2][2]<<endl; } ``` 这段源码体现了怎样巧妙运用辅助变量保存中间步骤的信息从而简化复杂逻辑运算的同时也满足了额外的要求[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值