其实标题我想写“心得体会与题解”的,后来,看着自己只有一道题ac,……
今天学长发来一个链接说有华南理工的校赛,本来今天要做gym的比赛来着,就先做这个了,
看着首页赫然写着
本次比赛难度跨度大,既适合0基础经过一个学期学习并至少掌握C++或JAVA进行编程的同学,也适合在区域赛取得奖项的同学。
然而看到题之后,慌得要死,因为从头看到尾一个我能做的都没有。甚至前半个小时左右,没有一个人提交代码。
正当自己慌慌张张还有点失望的时候,看见了一道题星星点点的有人通过,还挺多的……
于是在瞎开一题始终过不去的情况下换了这道题(我瞎开的题到现在为止还是0人通过)
链接:https://www.nowcoder.com/acm/contest/94/H
来源:牛客网
对称与反对称
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
给出一个N*N的方阵A。构造方阵B,C:
使得A = B + C.其中 B为对称矩阵,C为反对称矩阵。
对于方阵S中的任意元素,若(S)ij = (S)ji,则称S为对称矩阵
对于方阵T中的任意元素,若(T)ij = -(T)ji,则称T为反对称矩阵
注意,所有运算在模M意义下
输入描述:
输入包含多组数据,处理到文件结束
每组数据,第一行包含两个正整数N,M(1 <= N <= 1000, 1 <= M <= 1000,000,001)分别表示方阵大小与模数,其中M必定为奇数。
接下来的N行,每行有N个非负整数,表示方阵A(0<=Aij<=1000,000,000)。
输出描述:
对于每组数据,将反对称矩阵$C$在$N$行中输出;
若不存在解,则输出"Impossible";
若存在多解,则输出任意解。
示例1
输入
2 19260817
0 1
1 0
输出
0 0
0 0
首先,朋友推出来一个公式,
t[i][j]=(a[i][j]-a[j][i])/2;
推导过程:A[i][j]=S[i][j]+T[i][j];
A[j][i]=S[i][j]-T[i][j];(因为A矩阵转置了,所以,加的位置不变,减的位置(T数组)应该转置一下也就是负的和正的互相颠倒)
上面两式相加,得
A[j][i]+A[i][j]=2S[i][j];
两式相减
A[i][j]+A[j][i]=2T[i][j]
证毕。
我拿到了这个公式,冷静了一下,开始上代码,先小数据范围跑一下,自己出了个数据验证了一下,验证出来这个公式是正确的。
后来,看题意要取模,我就拿出来昨天Wannafly的板子来取模(除以2就涉及到分数取模)
很快套完却发现过不了。之后就是漫长的debug……把所有的矩阵ABC全都输出了,确定计算过程没错!但是就是过不了……
这时已经找不出什么错误了,还是一样的焦急,已经过去两个半小时……突然跳出来一条提示:
“负数的取模要加上m之后,变成正数再取模,答案全是正数”
恍然大悟。赶紧改代码……奇迹发生!……emmm,能在过题人数如此稀少的比赛里过一道题真的很激动!!
好了,show you the code!!!
#include
using namespace std;
long long int a[1010][1010],t[1010][1010];
double fsa[1010][1010],fsans[1010][1010];//这两个一个是保存小数据原始答案,一个保存那个正对称矩阵
int main()
{
int n;long long m;
while(scanf("%d%lld",&n,&m)!=EOF)
{
for(int i=0;i
别的也就不多说了!还是自己实力不行,训练太少,思考太少!多多训练才是王道!
多打、敢打比赛,才能认清自己的不足!