07:矩阵归零消减序列和
总时间限制: 1000ms 内存限制: 65536kB
描述
给定一个n*n的矩阵(3 <= n <= 100,元素的值都是非负整数)。通过(n-1)次实施下述过程,可把这个矩阵转换成一个1*1的矩阵。每次的过程如下:
首先对矩阵进行行归零:即对每一行上的所有元素,都在其原来值的基础上减去该行上的最小值,保证相减后的值仍然是非负整数,且这一行上至少有一个元素的值为0。
接着对矩阵进行列归零:即对每一列上的所有元素,都在其原来值的基础上减去该列上的最小值,保证相减后的值仍然是非负整数,且这一列上至少有一个元素的值为0。
然后对矩阵进行消减:即把n*n矩阵的第二行和第二列删除,使之转换为一个(n-1)*(n-1)的矩阵。
下一次过程,对生成的(n-1)*(n-1)矩阵实施上述过程。显然,经过(n-1)次上述过程, n*n的矩阵会被转换为一个1*1的矩阵。
请求出每次消减前位于第二行第二列的元素的值。
输入
第一行是一个整数n。
接下来n行,每行有n个正整数,描述了整个矩阵。相邻两个整数间用单个空格分隔。
输出
输出为n行,每行上的整数为对应矩阵归零消减过程中,每次消减前位于第二行第二列的元素的值。
样例输入
3
1 2 3
2 3 4
3 4 5
样例输出
3
0
0
思路:二重for处理最小值,删除操作用赋值解决,然后修改矩阵规模
#include<iostream>
using namespace std;
int n,a[105][105];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
while(n >= 1)
{
cout<<a[2][2]<<endl;
for(int x = 1;x <= n;x ++)//第一次归零
{
int minn = 2147483647;
for(int y = 1;y <= n;y ++)
if(a[x][y] < minn) minn = a[x][y];
for(int y=1;y<=n;y++)
a[x][y] -= minn;
}
for(int x = 1;x <= n;x ++)//第二次归零
{
int minn = 2147483647;
for(int y = 1;y <= n;y ++)
if(a[y][x] < minn) minn = a[y][x];
for(int y = 1;y <= n;y ++)
a[y][x] -= minn;
}
for(int x = 2;x <= n-1;x ++)//削减行
for(int y = 1;y <= n;y ++)
a[x][y] = a[x+1][y];
for(int x = 1;x <= n-1;x++)//削减列
for(int y = 2;y <= n-1;y++)
a[x][y] = a[x][y+1];
n --;
}
return 0;
}
12:变幻的矩阵
总时间限制: 1000ms 内存限制: 65536kB
描述
有一个N x N(N为奇数,且1 <= N <= 10)的矩阵,矩阵中的元素都是字符。这个矩阵可能会按照如下的几种变幻法则之一进行变幻(只会变幻一次)。
现在给出一个原始的矩阵,和一个变幻后的矩阵,请编写一个程序,来判定原始矩阵是按照哪一种法则变幻为目标矩阵的。
- 按照顺时针方向旋转90度;
如:
1 2 3 7 4 1
4 5 6 变幻为 8 5 2
7 8 9 9 6 3
按照逆时针方向旋转90度;
如:
1 2 3 3 6 9
4 5 6 变幻为 2 5 8
7 8 9 1 4 7中央元素不变(如下例中的 5),其他元素(如下例中的3)与“以中央元素为中心的对应元素”(如下例中的7)互换;
如:
1 2 3 9 8 7
4 5 6 变幻为 6 5 4
7 8 9 3 2 1保持原始矩阵,不变幻;
如果 从原始矩阵 到 目标矩阵 的变幻,不符合任何上述变幻,请输出5
输入
第一行:矩阵每行/列元素的个数 N;
第二行到第N+1行:原始矩阵,共N行,每行N个字符;
第N+2行到第2*N+1行:目标矩阵,共N行,每行N个字符;
输出
只有一行,从原始矩阵 到 目标矩阵 的所采取的 变幻法则的编号。
样例输入
5
a b c d e
f g h i j
k l m n o
p q r s t
u v w x y
y x w v u
t s r q p
o n m l k
j i h g f
e d c b a
样例输出
3
思路:推出几种情况下 两个矩阵应该是怎样对应的 把规律套用判断每个格子是否相等 相等就++ 最后判断总数是否于总格子数相等 相等就对应规律输出 否则就是-1
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char dt[11][11],mp[11][11];
int n,a,b,c,d;
int main()
{
cin >> n;
int s = n * n;
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= n;j ++)
cin >> dt[i][j];
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= n;j ++)
cin >> mp[i][j];
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= n;j ++)
{
if(dt[i][j] == mp[j][n-i+1]) a ++;
if(dt[i][j] == mp[n-j+1][i]) b ++;
if(dt[i][j] == mp[n-i+1][n-j+1]) c ++;
if(dt[i][j] == mp[i][j]) d ++;
}
if(a == s) puts("1");
else if(b == s) puts("2");
else if(c == s) puts("3");
else if(d == s) puts("4");
else puts("5");
return 0;
}
14:扫雷游戏地雷数计算
总时间限制: 1000ms 内存限制: 65536kB
描述
扫雷游戏是一款十分经典的单机小游戏。它的精髓在于,通过已翻开格子所提示的周围格地雷数,来判断未翻开格子里是否是地雷。
现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格的周围格地雷数。
注:每个格子周围格有八个:上、下、左、右、左上、右上、左下、右下。
输入
第一行包含两个整数n和m,分别表示雷区的行数和列数。1 <= n <= 100, 1 <= m <= 100。
接下来n行,每行m个字符,‘*’表示相应格子中是地雷,‘?’表示相应格子中无地雷。字符之间无任何分隔符。
输出
n行,每行m个字符,描述整个雷区。若相应格中是地雷,则用‘*’表示,否则用相应的周围格地雷数表示。字符之间无任何分隔符。
样例输入
3 3
*??
???
?*?
样例输出
*10
221
1*1
思路:char存图 如果是星号把附近的八个点都更新一下 同时输出的时候输出“*”继续遍历图
如果是?的点输出更新完后的值就好了~~~
代码:
#include<iostream>
#include<cstring>
using namespace std;
char mp[105][105];
int dt[105][105];
int main()
{
int n,m;
cin >> n >> m;
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
cin >> mp[i][j];
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
{
if(mp[i][j] == '*')
{
dt[i-1][j] ++;
dt[i+1][j] ++;
dt[i][j-1] ++;
dt[i][j+1] ++;
dt[i-1][j-1] ++;
dt[i-1][j+1] ++;
dt[i+1][j-1] ++;
dt[i+1][j+1] ++;
}
}
for(int i = 1;i <= n;i ++)
{
for(int j = 1;j <= m;j ++)
{
if(mp[i][j] == '*')
{
cout << '*';
continue;
}
cout << dt[i][j];
}
cout << endl;
}
return 0;
}