[关闭]
@exut 2024-10-17T05:19:50.000000Z 字数 877 阅读 158

20241017晚自习

刷题


好困,想搞T

[CEOI2024] 文本编辑器

奇怪题

假如他键盘也坏了不能换行,那就是一个很简单的模拟可以搞定的

大概可以想到答案的组成:

1.直接走

2.从起点先到某一行开头再走

3.从起点先到某一行结尾再走

这个能感性理解到,用左右键换行的次数应该不是很多,仔细想能发现 ,最多两次

有了这些结论就直接求就行了

维护第一部分答案用了个st表,写的劣了一点,复杂度

[ABC203D] Pond

其实是一个经典套路来着但是确实没想起来

考虑二分答案一个 为所求,然后把矩阵里 的赋为 ,反之为 ,然后可以二维前缀和维护一个矩阵里面有几个大于等于 的数

做完了

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,k;
  4. int a[805][805];
  5. int b[805][805];
  6. bool check(int x){
  7. for(int i=1;i<=n;i++){
  8. for(int j=1;j<=n;j++){
  9. b[i][j]=(a[i][j]>x);
  10. b[i][j]=b[i-1][j]+b[i][j-1]-b[i-1][j-1]+b[i][j];
  11. }
  12. }
  13. int tot=0;
  14. for(int i=1;i+k-1<=n;i++){
  15. for(int j=1;j+k-1<=n;j++){
  16. int x1=i,x2=i+k-1;
  17. int y1=j,y2=j+k-1;
  18. int sum=b[x2][y2]+b[x1-1][y1-1]-b[x2][y1-1]-b[x1-1][y2];
  19. if(sum<=k*k/2) return 1;
  20. }
  21. }
  22. return 0;
  23. }
  24. int A;
  25. int main(){
  26. cin>>n>>k;
  27. for(int i=1;i<=n;i++){
  28. for(int j=1;j<=n;j++){
  29. cin>>a[i][j];
  30. A=max(A,a[i][j]);
  31. }
  32. }
  33. int l=0,r=A,ans=-1;
  34. while(l<=r){
  35. int mid=(l+r)>>1;
  36. if(check(mid)){
  37. r=mid-1;ans=mid;
  38. }
  39. else l=mid+1;
  40. }
  41. cout<<ans;
  42. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注