C题
一 题目
二 思路
我们设每行总和为x,每列的总和为y,那么会有x=y。一共有n行m列,那么矩阵的总和可以表示为nx或者my,那么nx=my。如果n和m不相同,而x=y,那么x和y只能是0。所以,当n不等于m时候,行或者列的总和只能是0。当n和m相同时则可以为任何数,这里为了方便,我们统一行或者列的总和都是0。
因为每次只能向下或者向右,不能向上或者向左,所以每次可以确定一个点的值是多少,随后依次确定每个点的值就可以知道答案。可以证明,当路线向右时,说明行方向至少还有两个未知数,这时候列方向就只有一个未知数,反之,路线向下时,行方向只有一个未知数。在知道总和为0的情况下,就可以依次求出每个值是多少了。
三 代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1010;
int arr[N][N];//读入数据
int prerow[N],precol[N];//第i行总和,第i列总和
string s;//读入数据
void solve()
{
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++)prerow[i]=0;//初始化
for(int j=1;j<=m;j++)precol[j]=0;//初始化
cin>>s;
for(int i=1;i<=n;i++)//求每行总和
{
for(int j=1;j<=m;j++)
{
cin>>arr[i][j];
prerow[i]+=arr[i][j];
}
}
for(int j=1;j<=m;j++)//求每列总和
{
for(int i=1;i<=n;i++)
{
precol[j]+=arr[i][j];
}
}
int i=1,j=1;
for(int k=0;k<n+m-2;k++)//每次确定一个点,让总和=0
{
if(s[k]=='R')
{
arr[i][j]=-precol[j];
precol[j]=0;
prerow[i]+=arr[i][j];
j++;
}
else
{
arr[i][j]=-prerow[i];
prerow[i]=0;
precol[j]+=arr[i][j];
i++;
}
}
arr[i][j]=-prerow[i],prerow[i]=0,precol[j]=0;
for(int i=1;i<=n;i++)//输出结果
{
for(int j=1;j<=m;j++)
{
cout<<arr[i][j]<<' ';
}
cout<<'\n';
}
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
int t;cin>>t;
while(t--)solve();
return 0;
}
D题
一 题目
二 思路
这道题要求需要的时间,其实就是稻草人移动的距离。那么我们不如把所有东西都扩大2倍,除了稻草人的移动距离还是1,而不是2。这样求出来的时间就是2倍时间了。
这道题分为两种情况:乌鸦在稻草人的左边和右边
1.乌鸦在第i个稻草人的右边
那就是第i个稻草人向左移动,同时第i-1个稻草人向右移动,迫使乌鸦与第i个稻草人重合后跳跃,此时会花费的时间就是两者之间的距离/2
2.乌鸦在第i个稻草人的左边
那么答案会是第i个稻草人移动到离乌鸦最近的位置,然后让乌鸦跳跃。乌鸦在稻草人左边是一定能让稻草人跳跃的,因为i-1个稻草人让乌鸦跳跃了k的位置,那么第i个稻草人在乌鸦左边,说说明距离一定小于k的位置。
3.如果最后没有稻草人让乌鸦跳跃了,那么就是最后一个稻草人慢慢推着乌鸦到目的地,加上距离即可。
三 代码
#include<iostream>
#define int long long
using namespace std;
const int N=200010;
int arr[N];
void solve()
{
int n,k,l;
cin>>n>>k>>l;
k*=2,l*=2;//将所有都扩大两倍,除了移动的单位距离,这样就把时间扩大两倍了
for(int i=1;i<=n;i++)
{
cin>>arr[i];
arr[i]*=2;
}
int ans=arr[1],x=k;//表示花费的时间*2,现在乌鸦到达哪个位置
for(int i=2;i<=n;i++)
{
if(arr[i]>x)//乌鸦在第i个稻草人右边
{
arr[i]=max(x,arr[i]-ans);
ans+=(arr[i]-x)/2;
x=(x+arr[i])/2+k;
}
else//乌鸦在第i个稻草人左边
{
arr[i]=min(x,arr[i]+ans);
x=arr[i]+k;
}
}
if(x<l)
{
ans+=l-x;
}
cout<<ans<<'\n';
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int t;
cin>>t;
while(t--)
{
solve();
}
return 0;
}