1 条题解
-
0
自动搬运
来自洛谷,原作者为

FL_sleake
漫漫月华无边搬运于
2025-08-24 23:04:03,当前版本为作者最后更新于2024-07-06 14:08:43,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
解题思路
维护坐标是简单的,注意走到边界处时及时停下即可。难点在于修改操作。
Subtask 1
由于 ,所以输出移动一次后的位置即可。
Subtask 2
其实没有用。由于 ,考虑按照题目描述的暴力修改 即可。
Subtask 3
首先需要发现对 进行偶数次修改等于没有修改,进行奇数次修改等于修改一次。
由于 ,所以每次修改的都是连续段,提高组选手可以考虑一个线段树砸上去。但是这是基础赛,所以我们考虑差分。维护一个 代表是否修改。如果第 次移动结束后需要修改,先把 异或上 ,再维护一个差分数组 ,将 也异或上 。在第 次移动前,让 异或上当前的 即可。
Subtask 4 & 5
发现 的加入并没有本质影响。实际上就是把 序列按照下标除以 的余数分成了 组。提高组选手可以考虑 个线段树砸上去,并没有刻意卡线段树。但是这是基础赛,所以我们考虑 个差分砸上去即可。和 Subtask 3 没有本质区别。
代码示例
#include<bits/stdc++.h> using namespace std; #define int long long int n,m,k,q; string s[510]; char c[200010]; int a[200010],b[200010]; int cnt[200100][25],flg[25]; //修改的函数 char Change(char x){ if(x=='U') return 'D'; if(x=='D') return 'U'; if(x=='L') return 'R'; if(x=='R') return 'L'; } signed main(){ cin>>n>>m>>q>>k; for(int i=1;i<=n;i++) cin>>s[i],s[i]=" "+s[i]; for(int i=1;i<=q;i++) cin>>c[i]>>a[i]>>b[i]; int x=1,y=1; for(int i=1;i<=q;i++){ int id; //判断除以k的余数 if(i%k==0) id=k; else id=i%k; flg[id]^=cnt[i][id]; //修改 if(flg[id]) c[i]=Change(c[i]); //移动 if(c[i]=='U') x=max(1ll,x-a[i]); if(c[i]=='D') x=min(n,x+a[i]); if(c[i]=='L') y=max(1ll,y-a[i]); if(c[i]=='R') y=min(m,y+a[i]); //修改,利用差分思想 if(s[x][y]=='X') flg[id]^=1,cnt[i+b[i]*k+k][id]^=1; } cout<<x<<" "<<y<<endl; return 0; }事实上空间复杂度可以优化到 ,因为上述代码中 数组实际用到的空间只有 。
#include<bits/stdc++.h> using namespace std; #define int long long int n,m,k,q; string s[510]; char c[200010]; int a[200010],b[200010]; int cnt[200100],flg[25]; //修改的函数 char Change(char x){ if(x=='U') return 'D'; if(x=='D') return 'U'; if(x=='L') return 'R'; if(x=='R') return 'L'; } signed main(){ cin>>n>>m>>q>>k; for(int i=1;i<=n;i++) cin>>s[i],s[i]=" "+s[i]; for(int i=1;i<=q;i++) cin>>c[i]>>a[i]>>b[i]; int x=1,y=1; for(int i=1;i<=q;i++){ int id; //判断除以k的余数 if(i%k==0) id=k; else id=i%k; flg[id]^=cnt[i]; //修改 if(flg[id]) c[i]=Change(c[i]); //移动 if(c[i]=='U') x=max(1ll,x-a[i]); if(c[i]=='D') x=min(n,x+a[i]); if(c[i]=='L') y=max(1ll,y-a[i]); if(c[i]=='R') y=min(m,y+a[i]); //修改,利用差分思想 if(s[x][y]=='X') flg[id]^=1,cnt[i+b[i]*k+k]^=1; } cout<<x<<" "<<y<<endl; return 0; }
- 1
信息
- ID
- 9064
- 时间
- 500ms
- 内存
- 512MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者