B. So Easy
题目:给出一个 n ∗ n n*n n∗n的矩阵·,矩阵初始时由0组成。对任意一行/列进行任意次的加1操作。然后将新的矩阵的某个元素置为-1。输入n和进行置-1操作后的矩阵。推出-1那个位置原来的值是多少。(保证只有一个 -1)
方法一
- 读入矩阵时记录 -1 的位置 ( a i , a j ) (ai,aj) (ai,aj)并将其置为0。遍历每一行,找到这一行的最小值,并使这一行的每一个元素减去这个最小值。然后遍历每一列执行同样操作。最后得到 − a r [ a i ] [ a j ] -ar[ai][aj] −ar[ai][aj]即所求值。注意找最小值时,不把 a r [ a i ] [ a j ] ar[ai][aj] ar[ai][aj]纳入比较。
- 代码:
#include<iostream>
#include<cstdio>
#include<cmath>
const int mx = 1000+10;
const int INF = 0x3f3f3f3f3f;
int ar[mx][mx];
using namespace std;
int main()
{
int n, ai, aj;
scanf("%d", &n);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
scanf("%d", &ar[i][j]);
if(ar[i][j] == -1)
{
ai = i;
aj = j;
ar[i][j] = 0;
}
}
}
int minn;
for(int i=1; i<=n; i++)
{
minn = INF;
for(int j=1; j<=n; j++)
{
if(i != ai || j != aj)
{
minn = min(minn, ar[i][j]);
}
}
for(int j=1; j<=n; j++)
{
ar[i][j] -= minn;
}
}
for(int j=1; j<=n; j++)
{
minn = INF;
for(int i=1; i<=n; i++)
{
if(i!=ai||j!=aj)
minn = min(minn,ar[i][j]);
}
for(int i=1; i<=n; i++)
{
ar[i][j] -= minn;
}
}
printf("%d\n",-ar[ai][aj]);
return 0;
}
方法二
- 显然,矩阵中每一个位置的值等于它所在的行的加1操作次数加上它所在的列的加1操作次数。假设在一个含 a r [ a i ] [ a j ] = − 1 ar[ai][aj]=-1 ar[ai][aj]=−1的田字格里,-1所在位置原来的值为 x 1 + y 1 x_1+y_1 x1+y1,其相邻的两边的值分别为 x 1 + y 2 x_1+y_2 x1+y2和 x 2 + y 1 x_2+y_1 x2+y1,其对角线位置的值为 x 2 + y 2 x_2+y_2 x2+y2。则可知( x 1 + y 2 x_1+y_2 x1+y2)+( x 2 + y 1 x_2+y_1 x2+y1)-( x 2 + y 2 x_2+y_2 x2+y2) = ( x 1 + y 1 x_1+y_1 x1+y1)。即我们所需要的求的值。(因为考虑到边界和角的问题,将-1在田字格里的位置分情况谈论了)
0 | 1 | 2 | 3 | ··· |
---|---|---|---|---|
1 | ··· | ··· | ··· | ··· |
2 | ··· | x 1 + y 1 x_1+y_1 x1+y1 | x 1 + y 2 x_1+y_2 x1+y2 | ··· |
3 | ··· | x 2 + y 1 x_2+y_1 x2+y1 | x 2 + y 2 x_2+y_2 x2+y2 | ··· |
··· | ··· | ··· | ··· | ··· |
- 代码:
#include<iostream>
#include<cstdio>
#include<cmath>
const int mx = 1000+10;
const int INF = 0x3f3f3f3f3f;
int ar[mx][mx];
using namespace std;
int main()
{
int n, ai, aj, ans;
scanf("%d", &n);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
scanf("%d", &ar[i][j]);
if(ar[i][j] == -1)
{
ai = i;
aj = j;
}
}
}
if(ai + 1 <= n && aj + 1 <= n)
{
ans = ar[ai][aj+1] + ar[ai+1][aj] - ar[ai+1][aj+1];
}
else if(ai - 1 >= 1 && aj + 1 <= n)
{
ans = ar[ai-1][aj] + ar[ai][aj+1] - ar[ai-1][aj+1];
}
else if(ai - 1 >= 1 && aj -1 >= 1)
{
ans = ar[ai][aj-1] + ar[ai-1][aj] - ar[ai-1][aj-1];
}
else if(ai + 1 <= n && aj + 1 <= n)
{
ans = ar[ai][aj-1] + ar[ai+1][aj] - ar[ai+1][aj-1];
}
printf("%d\n",ans);
return 0;
}
I. Base62
题目:输入 x , y , z x, y, z x,y,z。符号“0”——“9”代表0到9,“A”——“Z”代表10到35,“a”——“z”代表36到61。现在需要将以 x x x为基底的整数 z z z转换为以 y y y为基底的整数 z z z。
- 用Python直接大数运算
- 代码:
a = input().split(); #字符串组保存xyz
x = int(a[0]); y = int(a[1])
z = list(a[2]);
z.reverse(); #反转
sum = 0; b = 1;
for i in z:
if i.isdigit():
sum += int(i)*b
elif i.islower():
sum += ((ord(i)-ord('a'))+36)*b #ord函数返回ASCLL值
elif i.isupper():
sum += ((ord(i)-ord('A'))+10)*b
b *= x #x的幂增长
if sum == 0:
print(0)
else:
ans = []
while sum > 0:
ans.append(sum%y)
sum = sum//y #sum就等于sum//y的小数部分
ans.reverse()
for i in ans:
if i < 10:
print(i,end='')
elif i < 36:
print(chr(ord('A')+i-10),end='')
else:
print(chr(ord('a')+i-36),end='')
N. Fibonacci Sequence
直接输出的水题