dtoj4697. 格

dtoj4697. 格

有一个 nm 列的矩阵,初始所有位置的权值都为 0.

开始时,你在格子 (x,y) 上。

每天早上,每个格子里的权值都会增加 1.

每天下午,你可以留在当前格子,或瞬移到上下左右相邻格子中的一个。

每天晚上,你会获得当前格子里的权值,然后清空当前格。

求第 k 天晚上后,你所获权值的最大值。


Sol

先考虑n>1,m>1

1如果k<nm 那么直接走就可以。

2如果矩阵有曼哈顿回路,那么就一直走曼哈顿回路。

3否则先等着,到还剩nm天时把矩阵走满。

 

然后考虑n=1的情况。记起点到短的那一边长度Mi

先考虑1

如果可以k>=MI+m 那就先走到一边然后3

否则先向短的那边走(m-Mi-1)步,然后往另一边

复制代码
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
#define mod 998244353
using namespace std;
ll T,n,m,x,y,k,n2=499122177,ans;
ll S(ll l,ll r){
    l%=mod,r%=mod;
    return ((l+r)%mod)*((r-l+1)%mod)%mod*n2%mod;
}
void work(){
    scanf("%lld%lld%lld%lld%lld",&n,&m,&x,&y,&k);
    if(n>m)swap(n,m),swap(x,y);
    if(n==1){
        ll Mi=min(y,m-y+1),Mx=max(y,m-y+1);
        if(k<=Mx)ans=S(1,k);
        else if(k>=m+Mi)ans=S(k-m+1,k);
        else {
            
            ll d=(k+Mi-m+1)/2;
            ans=S(d,k);
        }
    }
    else ans=S(max(k-n*m+1,0LL),k);
    ans=(ans%mod+mod)%mod;
    printf("%lld\n",ans);
}
int main(){
    for(scanf("%lld",&T);T--;work());
    return 0;
}
View Code
复制代码

 

posted @   liankewei123456  阅读(172)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示