原题:

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$的范围很大,直接询问$26^2$次进行一次选择排序就可以了。

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

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

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

#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;
}

  

最新文章

  1. 多线程映射工具——ThreadLocal
  2. iOS中富文本NSMutableAttributedString的用法
  3. SpingMvc中的异常处理
  4. python问题记录
  5. java实现文件及目录压缩
  6. 用oop分析场景,写出代码。房间里,有人、猫、老鼠在睡觉,然后猫醒了发出叫声,叫声惊醒了人,人从床上坐起来,惊醒了老鼠,老鼠开始逃跑。
  7. 《JavaScript高级程序设计》学习笔记12篇
  8. mysql php nginx 源码包下载地址
  9. iOS开发的22个奇谲巧技
  10. yii2.0的gii生成代码bug
  11. PHP - PDO 之 mysql 基础操作
  12. Collecting Bugs poj2096 概率DP
  13. unity 网页加载AB问题
  14. Mysql在sql中截取时间类型字段的年月日
  15. setjmp/longjmp
  16. [转] Node.js使用MongoDB3.4+Access control is not enabled for the database解决方案
  17. git 修改客户端用户名和密码
  18. React-native-camera error with Expo: undefined is not an object (evaluating &#39;CameraManager.Aspect&#39;)
  19. Expo大作战(十)--expo中的App Icon,expo中的Assets,expo中的ErrorHandling错误处理
  20. com.baidu.mapapi.CoordType

热门文章

  1. JEval使用实例
  2. 我的Android进阶之旅------&amp;gt;Android中ListView中嵌套(ListView)控件时item的点击事件不起作的问题解决方法
  3. 《python源代码剖析》笔记 Python虚拟机框架
  4. hdu 4850 字符串构造---欧拉回路构造序列 递归+非递归实现
  5. C# 手动编写 DataSet,DataTable 及遍历DataSet中的数据
  6. C# Task 源代码阅读(2)
  7. openStack enscaption
  8. PCB拼板之单一矩形排样算法
  9. hihoCoder 1187
  10. C - Anton and Danik