CF 496C(Removing Columns-贪心取字典序)

解决了一个关于优化表格列删除数量的问题,目标是通过最少的列删除操作使得表格中行的字典序形成递增顺序。通过贪心策略逐列判断并决定是否保留,最终计算所需的最小删除次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A. Removing Columns
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given an n × m rectangular table consisting of lower case English letters. In one operation you can completely remove one column from the table. The remaining parts are combined forming a new table. For example, after removing the second column from the table

abcd
edfg
hijk

 

we obtain the table:

acd
efg
hjk

 

A table is called good if its rows are ordered from top to bottom lexicographically, i.e. each row is lexicographically no larger than the following one. Determine the minimum number of operations of removing a column needed to make a given table good.

Input

The first line contains two integers  — n and m (1 ≤ n, m ≤ 100).

Next n lines contain m small English letters each — the characters of the table.

Output

Print a single number — the minimum number of columns that you need to remove in order to make the table good.

Sample test(s)
input
1 10
codeforces
output
0
input
4 4
case
care
test
code
output
2
input
5 4
code
forc
esco
defo
rces
output
4
Note

In the first sample the table is already good.

In the second sample you may remove the first and third column.

In the third sample you have to remove all the columns (note that the table where all rows are empty is considered good by definition).

Let strings s and t have equal length. Then, s is lexicographically larger than t if they are not equal and the character following the largest common prefix of s and t (the prefix may be empty) in s is alphabetically larger than the corresponding character of t.


题目大意:有若干长度相等的字符串依次排列。问至少删除若干列,才能使字符串从上到下字典序单调不降。

显然,第一行如果不满足字典序一定要删。

如果满足字典序(如果前缀不同可分开考虑),那么取这一段一定不劣

(因为对于每个前缀一致的一段,

eg1:

AAABxxxx。。

AAACxxxx。。

可以看到由于前缀不同,后面x可乱取。

eg2:

AAABxxxx。。

AAABxxxx。。

前缀一样,对后面不影响还是要保证字典序。

∴贪心,从左到右每列能留就留。


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define MAXN (100+10)
long long mul(long long a,long long b){return (a*b)%F;}
long long add(long long a,long long b){return (a+b)%F;}
long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}
typedef long long ll;
char a[MAXN][MAXN];
int pre[MAXN];
int main()
{
//	freopen("Columns.in","r",stdin);
//	freopen(".out","w",stdout);
	int n,m;
	cin>>n>>m;
	For(i,n) scanf("%s",a[i]+1),pre[i]=1;
	int ans=0;
	For(j,m) 
	{
		bool flag=0;
		Fork(i,2,n) 
		{
			if (i==pre[i]) continue;
			if (pre[i]<i)
			{
				if (a[i][j]<a[i-1][j]) {flag=1;break;}
			}	
			
		}
		ans+=flag;
		
		if (flag==0)
		{
			Fork(i,2,n)
			{
				if (i==pre[i]) continue;
				if (pre[i]<i&&a[i][j]!=a[i-1][j]) pre[i]=i;
				else pre[i]=pre[i-1];
			}
		} 
		
	} 
	cout<<ans<<endl;
	
	return 0;
}



学生选课系统是一个常见的应用程序,用于管理学生的选课信息。在C语言中,可以使用文件操作和算法来实现学生选课系统的功能。 以下是一个简单的C语言学生选课系统的示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> // 定义课程结构体 typedef struct { char courseCode[10]; char courseName[50]; char courseProperty[20]; char semester[20]; int credit; } Course; // 定义学生结构体 typedef struct { char studentID[10]; char studentName[50]; Course courses[10]; int numCourses; } Student; // 函数声明 void displayMenu(); void searchCourse(Student* student); void displayCourseInfo(Student* student); void addCourse(Student* student); void removeCourse(Student* student); int main() { Student student; student.numCourses = 0; int choice; do { displayMenu(); printf("Enter your choice: "); scanf("%d", &choice); switch (choice) { case 1: searchCourse(&student); break; case 2: displayCourseInfo(&student); break; case 3: addCourse(&student); break; case 4: removeCourse(&student); break; case 5: printf("Exiting the program...\n"); break; default: printf("Invalid choice. Please try again.\n"); break; } } while (choice != 5); return 0; } // 显示菜单 void displayMenu() { printf("-- Student Course Registration System ---\n"); printf("1. Search course\n"); printf("2. Display course information\n"); printf("3. Add course\n"); printf("4. Remove course\n"); printf("5. Exit\n"); } // 搜索课程 void searchCourse(Student* student) { // 根据菜单选择查询字段,实现相应的查找算法 // 这里只是一个示例,具体的实现需要根据需求进行编写 printf("Searching course...\n"); } // 显示课程信息 void displayCourseInfo(Student* student) { // 分屏显示课程信息,每屏10条课程记录,按任意键继续 // 这里只是一个示例,具体的实现需要根据需求进行编写 printf("Displaying course information...\n"); } // 添加课程 void addCourse(Student* student) { // 添加课程到学生的选课列表中 // 这里只是一个示例,具体的实现需要根据需求进行编写 printf("Adding course...\n"); } // 移除课程 void removeCourse(Student* student) { // 从学生的选课列表中移除课程 // 这里只是一个示例,具体的实现需要根据需求进行编写 printf("Removing course...\n"); } ``` 这个示例中,我们使用了结构体来定义课程和学生的信息。通过菜单选择,可以进行课程的搜索、课程信息的显示、课程的添加和课程的移除等操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值