Code Forces 496 C. Removing Columns(贪心)

Description
给定n个长为m的字符串,现在要求字符串从上到下遵循字典序,可以通过完整的删除某一列字母来调整,问最少删除多少列能达到使字符串满足字典序的要求(允许两个字符串完全相同,允许把所有列都删光)
Input
第一行两个整数n和m表示字符串数和每个字符串的长度,之后n行每行一个长度为m的字符串
Output
输出为使得从上到下字典序非严格递增要删去的最少列数
Sample Input
4 4
case
care
test
code
Sample Output
2
Solution
根据字典序的特点我们知道如果一个字符串前面的元素已经小于另一个字符串对应位置的元素,那么就不用考虑后面元素的相对大小。用一个数组pre[i]记录第i行前端是否存在一个元素小于等于第i+1行的对应元素,从第1列开始枚举,对于列j枚举行i,如果pre[i]就不用比较,否则枚举第i行与第i+1行所有元素判断是否满足调价,如果不满足就ans++,满足就更新pre数组的值
Code

#include<stdio.h>
#include<string.h>
#define maxn 111
int n,m,pre[maxn],flag[maxn];
char t[maxn][maxn];
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0;i<n;i++)
            scanf("%s",t[i]);
        memset(pre,0,sizeof(pre));
        int ans=0,mark;
        for(int j=0;j<m;j++)
        {
            memset(flag,0,sizeof(flag));
            int mark=1;//标记当前列是否需要被删 
            for(int i=0;i<n-1;i++)
            {
                if(pre[i]) continue;//这两行已经满足字典序不需要再比 
                if(t[i][j]<t[i+1][j]) flag[i]=1;
                else if(t[i][j]>t[i+1][j]) 
                {
                    mark=0;
                    ans++;
                    break;
                }
            }
            if(mark)//这一列不删就更新pre数组的值 
                for(int i=0;i<n-1;i++)
                    if(flag[i]) pre[i]=1;
        }
        printf("%d\n",ans);
    }
    return 0;
}

你可能感兴趣的:(Code Forces 496 C. Removing Columns(贪心))