题意:给出n行string 长度都为m (n,m<=50),一个游标指向n行string的第一个字符, password长度为n 由n行string游标所指的字符组成,Password至少包含一个数字,字符和字母,移动游标消耗1 求最小消耗.
消耗最小,只需要有三行满足条件即可,多的没意义,,暴力O(n^3)枚举这三行,预处理每行变化的最小代价即可.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e3+20;
const int inf=1e5;
char s[N][N];
int d[N][3];//d[i][k] 第i行变为数字||字符||'*'#''&'的最小代价
int main()
{
int n,m;
while(cin>>n>>m)
{
for(int i=1;i<=n;i++)
{
scanf("%s",s[i]+1);
d[i][0]=d[i][1]=d[i][2]=inf;
for(int j=1;j<=m;j++)
{
if(s[i][j]>='0'&&s[i][j]<='9')
d[i][0]=min(d[i][0],min(j-1,m+1-j));
else if(s[i][j]>='a'&&s[i][j]<='z')
d[i][1]=min(d[i][1],min(j-1,m+1-j));
else
d[i][2]=min(d[i][2],min(j-1,m+1-j));
}
}
//因为肯定有三行分别指向数字,字母和字符 n<=50暴力枚举这三行即可
int ans=inf;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j) continue;
for(int k=1;k<=n;k++)
{
if(k==i||k==j) continue;
int t=d[i][0]+d[j][1]+d[k][2];
ans=min(ans,t);
}
}
}
cout<<ans<<endl;
}
return 0;
}