题意:相当于比大小的赌博计算赌徒一共需要支出多少赌资
比大小的规则很简单,是
在这个游戏中,有一个套牌由n卡。每张卡都有m数字写在上面。每个n玩家从一副牌中只收到一张牌。
然后所有玩家成对玩,每对玩家只玩一次。因此,例如,如果总共有四个玩家,则进行六场比赛:第一场比赛对第二场比赛,第一场比赛对第三场比赛,第一场比赛对第四场比赛,第二场比赛对第三场比赛,第二场比赛对第四场比赛,第三场比赛对第四场比赛。
解:
一开始其实放纵自己用了一个铁会时间超限的方法,一分钟写出来了,但是智能过样例,第三个test就卡住了,就是输入时就进行相减了
错误示范:
#include<bits/stdc++.h>
using namespace std;
int t,n,m,u,ans;
int main()
{
cin>>t;
while(t--)
{
cin>>n>>m;
vector<int> a[30];
ans=0;
//输入第一行
for(int j=0; j<m; j++)
{
cin>>u;
a[0].push_back(u);
}
//后续
for(int i=1; i<n; i++)
{
for(int j=0; j<m; j++)
{
cin>>u;
a[i].push_back(u);
for(int k=0; k<i; k++)
{
ans+=abs(a[k][j]-a[i][j]);
}
}
}
cout<<ans<<endl;
}
return 0;
}
由于绝对值这个东西不确定,我们很讨厌,所以我们可以通过排序接触正负号的不确定性,使得我们算出的值符号被我们绝对掌握!
注意,由于列向相减和横向相减可不是一样的东西
所以我们要进行行列置换,我们可以通过一个二维数组在输入时就可以达到该目的
(注意这里输入完可以进行一个特判,如果只有一行数据那么没有进行博弈的其他对象,赌资将会是0,n=1时,可以直接输出0然后continue进行下一次判断
)
回到前面,如果n>1,接下来要对每列进行排序
排序之后我们可以发现规律:
拿这一列排序后为 1,2,3,4,5举例
由于顺序已经拍好了,1-2的绝对值等同于2-1,所以1-后面的值的绝对值等同于(2+3+4+5)-4*1
同理,2-后面的值等同于(3+4+5)-3*2
后面同理,且这样子我们可以保证是正数。
(设i从0开始)
那么通过找规律,可以发现改列最后的赌资就是a【i】*i - a【i】*(n-i-1)即a【i】*(2i-n+1)
把每一列的赌资算出来之后都加到ans中最终就能得出答案。
这道题错了很多次,主要原因一个是比较少使用vector,一个是没养成注意精度范围的习惯
首先,vector的定义可以直接带入变量开辟空间
vector<vector<int>>v(n,vector<int>(m))
因为题目说n和m在1到3e5之间且n*m小于3e5
3e5是不大的,但是如果之间vector<vector<int>>v(3e5,vector<int>(3e5)),那么开辟的空间大小就是9e10,爆掉了,所以要用输入的n和m来开辟空间。
(注意由于进行了行列转换,这里的一维要用m,二维用n)
其次,当定义vector时指定了大小,那么它就相当于这个大小的数组了,赋值时直接使用a【i】【j】=xxx就行,不可以a.push_back(xxx),因为push_back是在原来的基础上再开辟空间添加数据,而我们已经开辟好了空间,原本的基础上就是m*n的大小了(这就是为什么输入时直接cin>>a[j][i]而不用push_back)
最后,注意精度范围,数值大小在1到1e6之间,大范围数值涉及到乘法时就需要注意int还够不够充裕了,这里的ans涉及了,这里的i指的是1~n,n最大3e5,a【i】【j】最大1e6,一相乘就变成了3e11,所以必须用long long int,而vector中的数值也需要用long long int,对范围做判断即可,不做再多解释了。
所以这道题:
#include<bits/stdc++.h>
using namespace std;
int t,n,m,u;
long long int ans;
int main()
{
cin>>t;
while(t--)
{
cin>>n>>m;
vector<vector<long long int>> a(m,vector<long long int>(n));
ans=0;
//输入
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
cin>>a[j][i];
}
}
//特判
if(n==1){
cout<<"0"<<endl;
continue;
}
for(int j=0;j<m;j++){
sort(a[j].begin(),a[j].end());
for(int i=0;i<n;i++){
ans+=a[j][i]*(2*i+1-n);
}
}
cout<<ans<<endl;
}
return 0;
}