前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >AtCoder入门练习题B--题解报告

AtCoder入门练习题B--题解报告

作者头像
海天一树
发布2018-04-17 12:55:43
5140
发布2018-04-17 12:55:43
举报
文章被收录于专栏:海天一树海天一树

一、题目

https://practice.contest.atcoder.jp/tasks/practice_2

二、分析

这里有三组测试用例。

第一组N = 26, Q = 1000。因为N * N < Q,所以可用冒泡排序法。具体代码参考官方给的Sample Code。

第二组N = 26, Q = 100,由于询问次数只有100次,可用插入排序法处理。每插入一个数据前,先用二分查找法查找插入的位置,这样可提升排序速度。但是这样需要询问26log226次,还是不能通过所有的数据。这就要求我们需要对每一次询问的答案做一个记忆化处理,记录下小球的质量关系,然后根据这个质量关系就可以得出有序的数列,从而降低时间复杂度。

第三组N=5, Q=7。先比较第0个和第1个,第2个和第3个,第1个和第3个,再求第5个的位置,最后求第2个和第0个、第1个、第5个的位置关系。

三、代码

代码语言:javascript
复制
#include<bits/stdc++.h>
using namespace std;
char s[29], ans[29];
int cmp['Z'+5]['Z'+5];
int cnt = 0;
// 比较两个字符,如果a>b返回true,如果a<b返回false
bool cmp_char(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;
        }
    }
    return cmp[a][b];
}
// N为5时,调用此方法进行排序
void sort_N5(char c)
{
    if(cmp_char(c, s[1]))
    {
        if(cmp_char(c, s[2]))
        {
            s[3] = c;
        }
        else
        {
            s[3] = s[2];
            s[2] = c;
        }
    }
    else
    {
        if(cmp_char(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;
        }
    }
}
// N为26时,调用此方法进行排序
void sort_N26(char c)
{
    int l = 0, r = cnt;
    while(l < r)
    {
        int mid = (l + r) >> 1;
        if(cmp_char(c, ans[mid]))
        {
            l = mid + 1;
        }
        else
        {
            r = mid;
        }
    }
    cnt++;
    // 在新加入的c比原先的所有字符都大时,if条件成立
    // 比如原先的顺序为"AB",新加和的"C"比"B"大,即"AB"变为"ABC"时
    if(cmp_char(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';
    memset(cmp, -1, sizeof(cmp));
    if(N == 26) // Q=1000, 或Q=100
    {
        cnt = 0;
        ans[0] = s[0];
        ans[N] = '\0';
        for(int i = 1; i < N; i++)
        {
            sort_N26(s[i]);
        }
        printf("! %s\n", ans);
    }
    else        // N=5, Q=7
    {
        if(cmp_char(s[0], s[1]))
        {
            swap(s[0], s[1]);
        }
        if(cmp_char(s[2], s[3]))
        {
            swap(s[2], s[3]);
        }
        if(cmp_char(s[1], s[3]))
        {
            swap(s[0], s[2]);
            swap(s[1], s[3]);
        }
        /*
         * 至此,s[0]<s[1], s[2]<s[3], s[1]<s[3]
         * 还有两个问题:
         * s[5]放哪;s[2]与s[0]、s[1]谁大谁小
         */
        char temp = s[2];
        if(cmp_char(s[4], s[1]))
        {
            // 若s[4]>s[1],则比较s[4]与s[3]
            if(cmp_char(s[4], s[3]))
            {
                // s[4]>s[1], s[4]>s[3]
                // 把0、1、2、5这四个位置填满,便于调用sort_N5()
                s[2] = s[3];
            }
            else
            {
                // s[1]<s[4]<s[3]
                s[2] = s[4];
                s[4] = s[3];
            }
        }
        else
        {
            // 若s[4]<s[1],则比较s[4]与s[0]
            if(cmp_char(s[4], s[0]))
            {
                // s[0]<s[4]<s[1]
                s[2] = s[1];
                s[1] = s[4];
                s[4] = s[3];
            }
            else
            {
                // s[4]<s[0]<s[1]
                s[2] = s[1];
                s[1] = s[0];
                s[0] = s[4];
                s[4] = s[3];
            }
        }
        sort_N5(temp);
        printf("! %s\n", s);
    }
    return 0;
}

四、参考

https://www.cnblogs.com/TheRoadToAu/p/8463454.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 海天一树 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、题目
  • 二、分析
  • 三、代码
  • 四、参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档