whuoj1574 第K小数

来源:互联网 发布:怎样看懂乙肝五项数据 编辑:程序博客网 时间:2024/06/04 16:15

题目大意:给定一个长度为n的数,随意去掉其中的一个数,共有n个数,求其中第k小的数

思路:因为只去其中的一个数,所以比较相邻的两个数,就可以确定大小,若左边大于右边,则去掉右边的数肯定比去掉左边的数小,所以给定up=n,down=1.若遇到右边一位大与左边,去掉此位所得的数字的顺序是的up--大,相反,若小于,则是第down++大。若左边等于右边,则一直找下去,找到第一位和他不相等的数进行比较,大小规则和前面一样。如此标记下去,遇到n-k+1就是所求的结果。


#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <fstream>#include <algorithm>#include <cmath>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <iomanip>using namespace std;#define maxn 1000005#define MOD 1000000007#define mem(a , b) memset(a , b , sizeof(a))#define LL long long#define INF 1000000000char str[maxn];int arr;int flag = 0 , res = 0;void Find(int pos , int len){    flag = 1;    while(pos < len && str[pos+1] == str[pos]) pos ++;    if(str[pos+1] > str[pos]) res = -1;    else res = 1;    if(pos == len - 1) res = 0;    return;}int main(){    int n , k;    while(scanf("%d %d" , &n , &k) != EOF)    {       // while((a[i++] = getchar()) != '\n') str+=a[i-1];        scanf("%s" , str);        int up = n , down = 1;        int ans = 0;        int len = n;        flag = 0 , res = 0;        for(int i = 0 ; i < n - 1; i ++)        {            if(str[i] > str[i+1])            {                arr = up--;                flag = 0;            }            else if( str[i] == str[i+1])            {                if(!flag) Find(i , len);                if(res == 1) arr = up--;                else if(res == -1) arr = down ++;             //   else {ans = i ; break;}            }            else            {                arr = down ++;                flag = 0;            }            if(arr == n - k + 1)            {                ans = i;                break;            }         //  printf("%d " , arr[i]);        }       // printf("\n");        if(ans == 0) ans = n - 1;        while(ans > 0 && str[ans] == str[ans-1])        {            ans--;        }        printf("%d\n" , ans+1);;    }    return 0;}


0 0