[ICPC 2022 Nanjing R] 停停,昨日请不要再重现题解
题目描述
继 2018,2019,2020 和 2021 年成功承办赛事之后,南京航空航天大学(NUAA)将连续第五年承办国际大学生程序设计竞赛(ICPC)。
在 2018 与 2019 年,“中二之力”队与“三个顶俩”队为清华大学赢得了冠军。在 2020 与 2021 年,北京大学的“逆十字”队连续赢得冠军。该队也在达卡举办的第 45 届国际大学生程序设计竞赛全球总决赛中获得了亚军,创造了东大陆区域过去六年来的最佳成绩。让我们恭喜他们,同时也非常期待他们在 2022 年南京站的表现!
今年,将会有约 500 支队伍参与南京站的竞赛。本次竞赛将会颁发至多 35 项金奖,70 项银奖与 105 项铜奖。让我们期待选手们出色的表现!
虽然由于疫情,我们(又一次)无法在南京相聚,我们仍然需要感谢竞赛组委会与志愿者们的努力付出。感谢你们为本次竞赛做出的贡献!

在 2018 年的竞赛中,K 题《袋鼠谜题》要求选手为以下游戏构造一个操作序列:
谜题由一个 n 行 m 列的网格(1≤n,m≤20)组成,且有一些(至少 2 只)袋鼠位于网格中。玩家的目标是控制袋鼠并把它们聚集在同一个格子中。一些格子里有墙,袋鼠无法进入这些有墙的格子,而其它格子是空的。袋鼠可以从一个空格子移动到上,下,左,右相邻的另一个空格子中。
游戏开始时,每个空格子里都有一只袋鼠。玩家可以通过键盘上 U,D,L,R 四个按键控制袋鼠的移动。所有袋鼠会同时根据您按下的按键移动。
选手需要构造一个长度至多为 5×104 且由 U,D,L,R 组成的操作序列以达成目标。
在 2020 年的竞赛中,A 题《啊,昨日重现》要求选手构造一张输入地图,以证明以下代码并不是上述问题的解:
#include <bits/stdc++.h>
using namespace std;
string s = "UDLR";
int main()
{
srand(time(NULL));
for (int i = 1; i <= 50000; i++) putchar(s[rand() % 4]);
return 0;
}
在 2021 年的竞赛中,A 题《呀,昨日再次重现》同样要求选手为以下游戏构造操作序列:
本题中,网格中的每个格子都有恰好一只袋鼠。您需要构造一个仅由字符
U,D,L和R组成的操作序列。在应用该操作序列后,所有袋鼠必须聚集在指定格子 (a,b) 中。操作序列的长度不能超过 3(n−1)。同往常一样,所有袋鼠会根据您的命令同时移动。
在 2022 年的竞赛中,袋鼠题又回来啦!我们不知道为什么命题组的成员们那么喜欢袋鼠,但题目如下:
给定一张 n 行 m 列的网格,在位于第 ih 行第 jh 列的格子上有一个洞,其它每个格子都是空地并且都有一只袋鼠。
相似地,袋鼠可以被键盘上的 U,D,L,R 键控制。所有袋鼠会同时根据按下的按键移动。具体来说,对于一只位于第 i 行第 j 列的格子(用 (i,j) 表示)上的袋鼠:
- 按键 U:它会移动到 (i−1,j)。
- 按键 D:它会移动到 (i+1,j)。
- 按键 L:它会移动到 (i,j−1)。
- 按键 R:它会移动到 (i,j+1)。
如果一只袋鼠踩到了洞(也就是说,i=ih 且 j=jh)或者移动到了网格外面,它将被从网格上移除。
问题在于,ih 与 jh 的值是未知的。您只知道一个仅由字符 U,D,L,R 组成的操作序列,以及一个整数 k 表示应用这个操作序列之后,网格上恰有 k 只袋鼠存留。
请计算有多少位置可能存在洞。也就是说,计算满足以下条件的整数对 (ih,jh) 的数量:
- 1≤ih≤n,1≤jh≤m。
- 洞位于 (ih,jh)。
- 应用给定的操作序列后,网格上恰有 k 只袋鼠存留。
输入格式
有多组测试数据。第一行输入一个整数 T 表示测试数据组数,对于每组测试数据:
第一行输入三个整数 n,m 与 k(1≤n,m≤103,0≤k<n×m)表示网格的大小以及应用操作序列后网格上存留的袋鼠数量。
第二行输入一个字符串 s1s2⋯sl(si∈{‘U’,‘D’,‘L’,‘R’},1≤l≤106)表示操作序列。
保证所有数据 n×m 之和以及操作序列长度之和均不超过 106。
输出格式
每组数据输出一行一个整数表示有多少位置可能存在洞。
输入输出样例
输入 #1复制
3 4 5 3 ULDDRR 4 5 0 UUUUUUU 4 5 10 UUUUUUU
输出 #1复制
2 20 0
说明/提示
对于第一组样例数据,有 2 个位置可能存在洞。
第一个可能的位置是 (3,4)。

第二个可能的位置是 (4,3)。

思路
二位前缀和。
代码见下
#include<bits/stdc++.h>
using namespace std;
long long t,n,m,k,l1,l2,r1,r2,u1,u2,d1,d2,df,f[5006][5006],lk=0,ty,tx;
string s;
int main(){
cin>>t;
while(t--){
cin>>n>>m>>k;
l1=1;
l2=n;
r1=1;
r2=m;
u1=1;
u2=n;
d1=1;
d2=m;
cin>>s;
df=s.size();
for(int i=0;i<df;i++){
if(s[i]=='U'){
l1--;
l2--;
}
if(s[i]=='D'){
l1++;
l2++;
}
if(s[i]=='L'){
r1--;
r2--;
}
if(s[i]=='R'){
r1++;
r2++;
}
u1=max(u1,l1);
u2=min(u2,l2);
d1=max(d1,r1);
d2=min(d2,r2);
}
//cout<<u1<<" "<<u2<<" "<<d1<<" "<<d2<<endl;
if(u1>=u2+1||d1>=d2+1){
if(k==0){
cout<<n*m<<endl;
}
else{
cout<<0<<endl;
}
}
else if((u2-u1+1)*(d2-d1+1)<=k-1){
cout<<0<<endl;
}
else{
for(int i=0;i<=2*n+5;i++){
for(int j=0;j<=2*m+5;j++){
f[i][j]=0;
}
}
long long ss=n+1,t=m+1;
f[ss][t]=1;
for(int i=0;i<df;i++){
if(s[i]=='U'){
ss--;
}
if(s[i]=='D'){
ss++;
}
if(s[i]=='L'){
t--;
}
if(s[i]=='R'){
t++;
}
f[ss][t]=1;
}
for(int i=1;i<=2*n+5;i++){
for(int j=1;j<=2*m+5;j++){
f[i][j]+=(f[i-1][j]+f[i][j-1]-f[i-1][j-1]);
//cout<<i<<" "<<j<<" "<<f[i][j]<<endl;
}
}
lk=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
tx=n-i+1;
ty=m-j+1;
//cout<<f[tx+u2][ty+d2]-f[tx+u1-1][ty+d2]-f[tx+u2][ty+d1-1]+f[tx+u1-1][ty+d1-1]<<endl;
if(f[tx+u2][ty+d2]-f[tx+u1-1][ty+d2]-f[tx+u2][ty+d1-1]+f[tx+u1-1][ty+d1-1]==(u2-u1+1)*(d2-d1+1)-k){
lk++;
}
}
}
cout<<lk<<endl;
}
}
return 0;
}

浙公网安备 33010602011771号