开始觉得这道题是一个贪心发现每次操作很麻烦,一直到比赛结束也没想到什么好的办法。
题意:
有一个无限大的二维格子,从其中任意一点作为起点,按照所给的字符串WASD四个方向去移动,我们在字符串任意位置插入一个操作(WASD四个方向的一个),使走过方格所围成的矩形面积最小。
题解:
如果暴力考虑在某个位置插入的话,每次进行插入后再去检测这样时间复杂度会达到O(n2),很明显会超时。我们可以发现走过格子的高度不受左右变化的影响('A','D'操作不会对高度产生影响),同理宽度也不会被
上下方向所影响。
现在单独考虑高度的最小值。我们默认从(0,0)开始,用一个数组sum将每一个操作走后的高度求出来。就会得到一个关于高度变化的序列。我们会发现这个序列中相邻的两个不同元素相差为1。还可以得到高度变化后的最大值和最小值。如果不进行任何变化那它的高度为 (max-min+1)。
- 当最后一个最大值出现在第一个最小值之前,我们就可以将最大值后面所有的值全部加1。因此后面所有的最小值全部加1。这样高度就会变为(max-min)。
- 当最后一个最小值出现在第一个最大值之前,我们就可以将最小值后面所有的值全部减1。因此后面所有的最大值全部减1。这样高度就会变为(max-min)。
- 当最后一个最大值前面有最小值,可以发现后面所有值加1后,前面仍有最小值,答案不会变小。
- 当最后一个最小值前面有最大值,可以发现后面所有值减1后,前面仍有最大值,答案不会减小。
- 当最大值与最小值<2时,我们没有去变化的空间,所以答案不能发生改变。
综上所述,我们只要找到:最后一个最大值是否小于第一个最小值的位置且差值大于1或者最后一个最小值是否小于第一个最大值的位置且差值大于1就可以将答案缩小1。我们得出最小高度和最小宽度后,因为只能修改一次,我们只能修改高度或者宽度,所以要进行比较哪个更小。
代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf = 0x3f3f3f3f; 4 typedef long long ll; 5 const ll mod = 998244353; 6 char a[200010]; 7 int sum[2][200010],len; 8 int result(int maxn,int minn,int z) 9 { 10 if(maxn-minn<2) 11 { 12 return maxn-minn+1; 13 } 14 int maxfirst,maxsecond; 15 int minfirst,minsecond; 16 int flag1=0,flag2=0; 17 for(int i=0;i<=len;i++) 18 { 19 if(sum[z][i]==maxn&&flag1==0) 20 { 21 maxfirst=i; 22 flag1=1; 23 } 24 if(sum[z][i]==minn&&flag2==0) 25 { 26 minfirst=i; 27 flag2=1; 28 } 29 if(sum[z][i]==maxn) 30 { 31 maxsecond=i; 32 } 33 if(sum[z][i]==minn) 34 { 35 minsecond=i; 36 } 37 } 38 if(maxsecond+2<=minfirst) 39 { 40 return maxn-minn; 41 } 42 else if(minsecond+2<=maxfirst) 43 { 44 return maxn-minn; 45 } 46 else 47 { 48 return maxn-minn+1; 49 } 50 } 51 52 int main() 53 { 54 ios::sync_with_stdio(false); 55 cin.tie(0),cout.tie(0); 56 int T; 57 cin>>T; 58 while(T--) 59 { 60 cin>>a; 61 len = strlen(a); 62 int maxn1=0,maxn2=0; 63 int minn1=0,minn2=0; 64 for(int i=0;i<len;i++) 65 { 66 sum[0][i+1]=sum[0][i]; 67 sum[1][i+1]=sum[1][i]; 68 if(a[i]=='W') 69 { 70 sum[0][i+1]++; 71 } 72 else if(a[i]=='S') 73 { 74 sum[0][i+1]--; 75 } 76 else if(a[i]=='A') 77 { 78 sum[1][i+1]++; 79 } 80 else sum[1][i+1]--; 81 maxn1=max(maxn1,sum[0][i+1]); 82 maxn2=max(maxn2,sum[1][i+1]); 83 minn1=min(minn1,sum[0][i+1]); 84 minn2=min(minn2,sum[1][i+1]); 85 } 86 ll ans1=result(maxn1,minn1,0); 87 ll ans2=result(maxn2,minn2,1); 88 //cout<<ans1<<" "<<ans2<<endl; 89 ll ans= min(ans1*(maxn2-minn2+1),ans2*(maxn1-minn1+1)); 90 cout<<ans<<endl; 91 } 92 return 0; 93 }