C++RMQ算法—————A Magic Lamp

題目描述:

Kiki likes traveling. One day she finds a magic lamp, unfortunately the genie in the lamp is not so kind. Kiki must answer a question, and then the genie will realize one of her dreams. 
The question is: give you an integer, you are allowed to delete exactly m digits. The left digits will form a new integer. You should make it minimum. 
You are not allowed to change the order of the digits. Now can you help Kiki to realize her dream? 

輸入:

There are several test cases. 
Each test case will contain an integer you are given (which may at most contains 1000 digits.) and the integer m (if the integer contains n digits, m will not bigger then n). The given integer will not contain leading zero. 

輸出:

For each case, output the minimum result you can get in one line. 
If the result contains leading zero, ignore it. 

樣例輸入:

178543 4 
1000001 1
100001 2
12345 2
54321 2

樣例輸出:

13
1
0
123
321

思路分析:

其實這一題就是求數列刪出後的最小值。

我們可以先用RMQ求出數列區間的最小值。

之後我們要取len-m個數,那麼我們的第一個區間邊界就是1到m+1,爲什麼呢。

我們要取len-m個數,那麼就算是後面的都取,則是len-m+1,所以區間就是[1,m+1]。

最後我們在尋找過程中用暴力就可以尋找下一個節點的左端點(所尋的數的位置)。

代碼實現:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int len,n,m,dp[1005][25],s1[1005];
char s[1005];
int Get_quary(int l,int r)
{
	int k=(int)(log(double(r-l+1))/log(double(2)));
	return min(dp[l][k],dp[r-(1<<k)+1][k]);
}
int main()
{
	while(scanf("%s%d",s,&m)!=-1)
	{
	    len=strlen(s);
		int tot=0;
		if(m<=0)
		{
			puts(s);
			continue;
		}
		for(int i=0;i<len;i++)
			dp[i][0]=s[i]-'0';
		for(int j=1;(1<<j)<=len;j++)
            for(int i=0;i+(1<<j)-1<len;i++)
                dp[i][j]=min(dp[i][j-1],dp[i+(1<<j-1)][j-1]);
        int l=0,r=m;
        while(l<=r)
        {
        	int p=Get_quary(l,r);
        	tot++;
        	s1[tot]=p;
        	int i=l;
        	for(;i<=r;i++)
        		if(p+'0'==s[i])
        			break;
        	l=i+1;
        	r++;
		}
		int i;
		for(i=1;i<tot;i++)
			if(s1[i]>0)
				break;
        if(i==tot)
        {
            printf("0\n");
            continue;
        }
		for(;i<tot;i++)
			printf("%d",s1[i]);
		printf("\n");
		memset(dp,0,sizeof(dp));
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章