zoukankan      html  css  js  c++  java
  • Codeforces 844D Interactive LowerBound

    This is an interactive problem.

    You are given a sorted in increasing order singly linked list. You should find the minimum integer in the list which is greater than or equal to x.

    More formally, there is a singly liked list built on an array of n elements. Element with index i contains two integers: valuei is the integer value in this element, and nexti that is the index of the next element of the singly linked list (or -1, if the current element is the last). The list is sorted, i.e. if nexti ≠  - 1, then valuenexti > valuei.

    You are given the number of elements in the list n, the index of the first element start, and the integer x.

    You can make up to 2000 queries of the following two types:

    • ? i (1 ≤ i ≤ n) — ask the values valuei and nexti,
    • ! ans — give the answer for the problem: the minimum integer, greater than or equal to x, or ! -1, if there are no such integers. Your program should terminate after this query.

    Write a program that solves this problem.

    Input

    The first line contains three integers nstartx (1 ≤ n ≤ 50000, 1 ≤ start ≤ n0 ≤ x ≤ 109) — the number of elements in the list, the index of the first element and the integer x.

    Output

    To print the answer for the problem, print ! ans, where ans is the minimum integer in the list greater than or equal to x, or -1, if there is no such integer.

    Interaction

    To make a query of the first type, print ? i (1 ≤ i ≤ n), where i is the index of element you want to know information about.

    After each query of type ? read two integers valuei and nexti (0 ≤ valuei ≤ 109 - 1 ≤ nexti ≤ nnexti ≠ 0).

    It is guaranteed that if nexti ≠  - 1, then valuenexti > valuei, and that the array values give a valid singly linked list with start being the first element.

    Note that you can't ask more than 1999 queries of the type ?.

    If nexti =  - 1 and valuei =  - 1, then it means that you asked more queries than allowed, or asked an invalid query. Your program should immediately terminate (for example, by calling exit(0)). You will receive "Wrong Answer", it means that you asked more queries than allowed, or asked an invalid query. If you ignore this, you can get other verdicts since your program will continue to read from a closed stream.

    Your solution will get "Idleness Limit Exceeded", if you don't print anything or forget to flush the output, including the final answer.

    To flush you can use (just after printing a query and line end):

    • fflush(stdout) in C++;
    • System.out.flush() in Java;
    • stdout.flush() in Python;
    • flush(output) in Pascal;
    • For other languages see documentation.

    Hacks format

    For hacks, use the following format:

    In the first line print three integers nstartx (1 ≤ n ≤ 50000, 1 ≤ start ≤ n0 ≤ x ≤ 109).

    In the next n lines print the description of the elements of the list: in the i-th line print two integers valuei and nexti (0 ≤ valuei ≤ 109 - 1 ≤ nexti ≤ nnexti ≠ 0).

    The printed structure should be a valid singly linked list. In particular, it should be possible to reach all elements from start by following links nexti, and the last element end should have -1 in the nextend.

    Example
    input
    5 3 80
    97 -1
    58 5
    16 2
    81 1
    79 4
    output
    ? 1
    ? 2
    ? 3
    ? 4
    ? 5
    ! 81
    Note

    You can read more about singly linked list by the following link: https://en.wikipedia.org/wiki/Linked_list#Singly_linked_list

    The illustration for the first sample case. Start and finish elements are marked dark.


      题目大意 给定一个元素按升序排序的单向链表,给定开头的下标,查询大于等于x的最小值。每次可以询问一个位置的值和它的下一个元素的下标。询问不得超过1999次。

      这是一道有趣的题目。

      1)如果n不超过1999暴力for整个链表。

      2)否则随机1000个位置查值,然后找到第一个小于x的位置开始往后for。直到链表结束或者找到一个大于等于x的值。

      另外直接srand((unsigned) time (0))会被卡掉,所以但是随机函数就过了。

    Code

      1 /**
      2  * Codeforces
      3  * Problem#844D
      4  * Accepted
      5  * Time: 30ms
      6  * Memory: 500k
      7  */
      8 #include <bits/stdc++.h>
      9 using namespace std;
     10 typedef bool boolean;
     11 typedef pair<int, int> pii;
     12 
     13 typedef class Random {
     14     public:
     15         unsigned int pre;
     16         unsigned int seed;
     17         
     18         Random():pre(0), seed((unsigned) time (NULL)) {    }
     19         Random(int seed):pre(0), seed(seed) {    }
     20         
     21         /**
     22          * Generate a random number.
     23          * @return this function will return the random number it gernerated
     24          */
     25         unsigned int rand() {
     26 //            unsigned int ret = (seed * 7361238 + seed % 20037 * 1244 + pre * 12342 + 378211) * (seed + 134543);
     27 //            unsigned int ret = (seed * 7361238 + seed % 20037 * 1244 + pre * 12342 + 378211 + time(NULL) * pre) * (seed + 134543);
     28             unsigned int ret;
     29             if(ret & 1)
     30                 ret = (seed * 7361238 + seed % 20037 * 1245 + pre * 456451 + (time(NULL) * (pre * 5 + seed * 3 + 37)) + 156464);
     31             else
     32                 ret = (seed * 7361238 + seed % 20037 * 1241 + pre * 456454 + (time(NULL) * (pre * 7 + seed * 3 + 18)) + 156464);
     33             pre = seed;
     34             seed = ret;
     35             return ret;
     36         }
     37     
     38         /**
     39          * Generate a random number that between a variable low and a variable high.
     40          * @param low the variable low
     41          * @param high the variable high
     42          * @return if low is not more than high, it will return the random number or it will return 0
     43          */
     44         unsigned int rand(int low, int high){
     45             if(low > high)  return 0;
     46             int len = high - low + 1;
     47             return rand() % len + low;
     48         }
     49 }Random;
     50 
     51 Random r;
     52 int n, x, start;
     53 pii *val;
     54 pii ask(int p) {
     55     if(val[p].first != -1)    return val[p];
     56     pii rt;
     57     printf("? %d
    ", p);
     58     fflush(stdout);
     59     scanf("%d%d", &rt.first, &rt.second);
     60     return rt;
     61 }
     62 
     63 inline void init() {
     64     scanf("%d%d%d", &n, &start, &x);
     65     val = new pii[(n + 1)];
     66     for(int i = 1; i <= n; i++)
     67         val[i].first = -1;
     68 }
     69 
     70 inline void solve1() {
     71     pii data;
     72     for(int i = 0, p = start; i < n; i++) {
     73         data = ask(p);
     74         if(data.first >= x) {
     75             printf("! %d
    ", data.first);
     76             fflush(stdout);
     77             return;
     78         }
     79         p = data.second;
     80     }
     81     puts("! -1");
     82     fflush(stdout);
     83 }
     84 
     85 const int asktime = 1000;
     86 boolean *vis;
     87 int pos[asktime + 1];
     88 inline void solve2() {
     89     vis = new boolean[(n + 1)];
     90     memset(vis, false, sizeof(boolean) * (n + 1));
     91     vis[start] = true;
     92     for(int i = 1; i <= asktime; i++) {
     93         while(vis[(pos[i] = r.rand(1, n))]);
     94         vis[pos[i]] = true;
     95     }
     96     
     97     int s = start;
     98     pii dat = ask(start);
     99     for(int i = 1; i <= asktime; i++) {
    100         pii cmp = ask(pos[i]);
    101         if(cmp.first < x && cmp.first > dat.first)
    102             s = pos[i], dat = cmp;
    103     }
    104     
    105     while(s != -1) {
    106         if(dat.first >= x) {
    107             printf("! %d
    ", dat.first);
    108             fflush(stdout);
    109             return;
    110         }
    111         s = dat.second;
    112         dat = ask(s);
    113     }
    114     puts("! -1");
    115     fflush(stdout);
    116 }
    117 
    118 int main() {
    119     init();
    120     if(n <= 1999)
    121         solve1();
    122     else
    123         solve2();
    124     return 0; 
    125 }
  • 相关阅读:
    kettle入门(四) 之kettle取昨天时间&设置任意时间变量案例
    用法
    Win10任务计划调度执行kettle作业
    Kettle 合并记录和Merge Join组件实现数据增量迁移(数据同步比插入更新快)
    鼠标右键新建没有excel
    python的to_sql
    leetcode1105 Filling Bookcase Shelves
    leetcode96 Unique Binary Search Trees
    leetcode111 Minimum Depth of Binary Tree
    leetcode128 Longest Consecutive Sequence
  • 原文地址:https://www.cnblogs.com/yyf0309/p/7637865.html
Copyright © 2011-2022 走看看