今天把2017秦皇岛站作为练习赛,第一个签到题我就卡住了。。。
L题的大意是,给你一个字符串,只由字符“R”和“L”组成,遇到L就向左走一格,遇到R就向右走一格。如果你在第1格或第n格,就认为到达了出口。可以改变一些字符,使快速到达出口,把R变成L,或者把L变成R。任务是计算到达出口而必须改变的最小网格数。
就这个题我wa了三四次。。。我当时的错误代码是:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int main()
{
int t,n,m;
cin>>t;
while(t--)
{
cin>>n>>m;
char a[maxn];
int left=0,right=0,step=0,i;
char x;
for(i=1;i<=n;i++)
{
cin>>a[i];
}
for(i=1;i<=n;i++)
{
if(i<m&&i!=1)
{
if(a[i]=='L')
left++;
}
if(i==m) x=a[i];
if(i>m&&i!=n)
{
if(a[i]=='R')
right++;
}
}
if(left>right) //向左走
{
if(x=='L')
step=m-2-left;
else
step=m-1-left;
}
if(left<=right)
{
if(x=='R')
step=n-m-1-right;
else
step=n-m-right;
}
cout<<step<<endl;
}
return 0;
}
想法是,统计字符个数时不考虑两头的字母,因为它不影响结果。分别统计起始的那个格子左边的L和右边的R的数量,认为如果左边的L比右边的R多,就肯定往左走,反之往右走。往左走就用起始位置减去L的个数和最左边的一个,得到R的个数step=m-1-left,还要考虑到起始位置是R还是L,是R就把它变成L,step-1。是L就不变。往右走就同理。自认为正确。检查了很多次,都觉得其他的没有错误,后来才发现核心思路不对。左边的L比右边的R多,也不一定往左走。因为这样并不能保证左边的R比右边的L少,毕竟任务是找到要改变的最少的网格数,往左走就要把几个R变成L,往右走就把几个L变成R。同组的哥们儿一开始就想到应该统计左边的R和右边的L,我就很奇怪为什么自己想到的是统计左边的L和右边的R。。。
因此正确的代码是:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int main()
{
int t,n,m;
cin>>t;
while(t--)
{
cin>>n>>m;
char a[maxn];
int left=0,right=0,step=0,i;
char x;
for(i=1;i<=n;i++)
{
cin>>a[i];
}
for(i=1;i<=n;i++)
{
if(i<m&&i!=1)
{
if(a[i]=='R')
left++;
}
if(i==m) x=a[i];
if(i>m&&i!=n)
{
if(a[i]=='L')
right++;
}
}
if(x=='L')
right++;
else
left++;
if(left>right) //向左走
step=right;
if(left<=right)
step=left;
cout<<step<<endl;
}
return 0;
}
这次终于AC了,太期待这个结果了!
可能这样的错误别人不会犯吧。我知道自己的水平还很弱,但是我愿意看到努力之后美丽的结果。
为了梦想,我们唯有坚持!