「NOIP模拟赛」number
题目说明
一个集合有如下元素:1是集合元素;若P是集合的元素,则2*P+1,4*P+5也是集合的元
素,取出此集合中最小的K个元素,按从小到大的顺序组合成一个多位数,现要求从中删除M
个数位上的数字,使得剩下的数字最大,编程输出删除前和删除后的多位数字。
注:不存在所有数被删除的情况。
输入格式
输入仅一行,K,M的值,K,M均小于等于30000。
输入格式
输出为两行,第一行为删除前的数字,第二行为删除后的数字。
样例
Sample Input
5 4
Sample Output
137915
95
相关信息
文件名: number.pas/c/cpp
输入文件: number.in
输出文件: number.out
时限: 1s
空间限制: 64MB
题解
发现第一问大概枚举到420w即可
第二问用个栈贪心,保证前面尽量大
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #define ll long long #define N 4250000 using namespace std; ll read() { 	ll x=0,f=1;char ch=getchar(); 	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 	return x*f; } int K,m,tot; int ans,top; bool a[4300000]; int b[200005],t[10]; int q[200005]; void add(int x) { 	int top=0; 	while(x) 	{ 		t[++top]=x%10; 		x/=10; 	} 	for(int i=top;i;i--) 		b[++tot]=t[i]; } void solve() { 	int now=0; 	for(int i=1;i<=tot;i++) 	{ 		while(q[top]<b[i]&&top) 		{ 			top--; 			now++; 			if(m==now)return; 		} 		q[++top]=b[i]; 	} } int main() { 	K=read();m=read(); 	a[1]=1; 	for(int i=1;i<=N;i++) 		if(a[i]) 		{ 			if(i*2+1<=N)a[i*2+1]=1; 			if(i*4+5<=N)a[i*4+5]=1; 		} 	for(int i=1;i<=N;i++) 		if(a[i]) 		{ 			ans++; 			add(i); 			if(ans==K)break; 		} 	for(int i=1;i<=tot;i++)printf("%d",b[i]); 	puts(""); 	solve(); 	for(int i=1;i<=top;i++)printf("%d",q[i]); 	for(int i=m+top+1;i<=tot;i++)printf("%d",b[i]); 	puts(""); 	return 0; } | 
                                  Subscribe  
                            
                                                                        
                    