whuoj1574 第K小数

题目大意:给定一个长度为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 1000000000

char 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值