Typesetting math: 100%

非传统题初探——AtCoder Practice Contest #B - インタラクティブ練習 (Interactive Sorting)

原题

Time limit : 2sec / Memory limit : 256MB

Score : 300 points

Problem Statement

This is an interactive task.

There are N balls labeled with the first N uppercase letters. The balls have pairwise distinct weights.

You are allowed to ask at most Q queries. In each query, you can compare the weights of two balls (see Input/Output section for details).

Sort the balls in the ascending order of their weights.

Constraints

  • (N,Q)=(26,1000)(26,100), or (5,7).

Partial Score

There are three testsets. Each testset is worth 100 points.

  • In testset 1, N=26 and Q=1000.
  • In testset 2, N=26 and Q=100.
  • In testset 3, N=5 and Q=7.

Input and Output

First, you are given N and Q from Standard Input in the following format:

N Q

Then, you start asking queries (at most Q times). Each query must be printed to Standard Output in the following format:

? c1 c2

Here each of c1 and c2 must be one of the first N uppercase letters, and c1 and c2 must be distinct.

Then, you are given the answer to the query from Standard Input in the following format:

ans

Here ans is either < or >. When ans is <, the ball c2 is heavier than the ball c1, and otherwise the ball c1 is heavier than the ball c2.

Finally, you must print the answer to Standard Output in the following format:

! ans

Here ans must be a string of length N, and it must contain each of the first N uppercase letters once. It must represent the weights of the balls in the ascending order.

Judgement

  • After each output, you must flush Standard Output. Otherwise you may get TLE.
  • After you print the answer, the program must be terminated immediately. Otherwise, the behavior of the judge is undefined.
  • When your output is invalid or incorrect, the behavior of the judge is undefined (it does not necessarily give WA).

题目大意

这是一道交互题N 个小球用前 N 个大写字母编号每个小球有不同的重量

最多允许询问 Q每次询问可以比较两个小球的重量

按升序输出小球的质量

一共有三组数据子任务每组数据 100数据规模如下

子任务编号 N Q
1 26 1000
2 26 100
3 5 7

注意事项

  1. 输出一次就要刷新一次标准输出否则可能会被误判为 TLE
  2. 输出答案后程序必须立即退出否则 judger 的行为未定义
  3. 若输出答案不符合格式或不正确judger 的行为未定义不一定给出 WA

题解

第一次做交互题感觉很新鲜但是不知道该怎么做首先程序要与交互库进行交互根据交互库给出的信息判断小球的质量情况

对于第一个子任务由于 Q 的范围很大直接询问 262 次进行一次选择排序就可以了

对于第二个子任务由于询问次数只有 100我们假设数组已经有序二分一个小球质量的位置为 mid然后与这个位置的小球的质量进行比较进行一次插入排序即可需要询问 26log226还是不能通过所有的数据这就要求我们需要对每一次询问的答案做一个记忆化处理记录下询问小球的质量关系然后根据这个质量关系就可以得出有序的数列从而降低时间复杂度当然如果不记忆化也有可能能够通过这道题目123 次询问只比限制大一点

也可以写一个归并排序之类的东西当然需要记忆化记忆化每一个数大于哪些数小于哪些数或者只记忆化比这个数大的最小的数与比这个数小的最大的数

对于第三个子任务注意到这组数据非常特殊其实与给 5 个小球最多称 7 次求出质量关系的问题相同可以自己思考一下询问次数最小的方案

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include<bits/stdc++.h>
using namespace std;
 
char s[29], ans[29];
int cmp['Z'+5]['Z'+5];
int cnt = 0, QQ = 1;
 
bool cmp_user(const char a, const char b) {
    char cp;
    if(cmp[a][b]==-1) {
        printf("? %c %c\n", a, b);
        fflush(stdout);
        scanf(" %c", &cp);
        if(cp=='>') {
            cmp[a][b] = true;
            cmp[b][a] = false;
            return true;
        }
        else {
            cmp[a][b] = false;
            cmp[b][a] = true;
            return false;
        }
    }
    else return cmp[a][b];
}
 
void ins2(char c) {
    if(cmp_user(c, s[1])) {
        if(cmp_user(c, s[2])) s[3] = c;
        else s[3] = s[2], s[2] = c;
    } else {
        if(cmp_user(c, s[0])) {
            s[3] = s[2];
            s[2] = s[1];
            s[1] = c;
        } else {
            s[3] = s[2];
            s[2] = s[1];
            s[1] = s[0];
            s[0] = c;
        }
    }
}
 
void ins(char c) {
    int l = 0, r = cnt;
    while(l<r) {
        int mid = l+r>>1;
        if(cmp_user(c, ans[mid])) l = mid+1;
        else r = mid;
    }
    cnt ++;
    if(cmp_user(c, ans[r])) r ++;
    for(int i=cnt; i>=r+1; i--) ans[i] = ans[i-1];
    ans[r] = c;
}
 
int main() {
    int N, Q;
    scanf("%d%d", &N, &Q);
     
    for(int i=0; i<26; i++) s[i] = (char)(i+'A');
    s[N] = '\0';
     
    if(N==26) {
        memset(cmp, -1, sizeof(cmp));
        cnt = 0;
        ans[0] = s[0];
        ans[N] = '\0';
        for(int i=1; i<N; i++) ins(s[i]);
         
        printf("! %s\n", ans);
    } else {
        memset(cmp, -1, sizeof(cmp));
        if(cmp_user(s[0], s[1])) swap(s[0], s[1]);
        if(cmp_user(s[2], s[3])) swap(s[2], s[3]);
        if(cmp_user(s[1], s[3])) {
            swap(s[0], s[2]);
            swap(s[1], s[3]);
        }
        char x = s[2];
        if(cmp_user(s[4], s[1])) {
            if(cmp_user(s[4], s[3])) {
                s[2] = s[3];
                ins2(x);
            } else {
                s[2] = s[4];
                s[4] = s[3];
                ins2(x);
            }
        } else {
            if(cmp_user(s[4], s[0])) {
                s[2] = s[1];
                s[1] = s[4];
                s[4] = s[3];
                ins2(x);
            } else {
                s[2] = s[1];
                s[1] = s[0];
                s[0] = s[4];
                s[4] = s[3];
                ins2(x);
            }
        }
        printf("! %s\n", s);
    }
    return 0;
}

  

posted @   baka  阅读 (1495)  评论 (1编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10 年 + .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI 与. NET 技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT / 综述] AI Agent 的设计模式综述
点击右上角即可分享
微信分享提示