Loading

【NOIP2015模拟11.4】JZOJ8月6日提高组T1 刷题计划

【NOIP2015模拟11.4】JZOJ8月6日提高组T1 刷题计划

题目

在这里插入图片描述
在这里插入图片描述

题解

题意
\(n\)道题,编号为1~\(n\)
给出\(m\)次操作
每次操作有3种类型
1 \(x\) 表示交了\(AC\)的代码在编号为\(x\)的题
2 \(x\)表示交了没有\(AC\)的代码在编号为\(x\)的题
3 表示询问当前做过的题目中从来没有\(AC\)的题,晚交的先输出
对于每个3询问,输出前20个
分析
既然\(m\)只有100
那为什么不打暴力呢
对于每种操作
是1的话给题目打个\(AC\)标记
是2的话放入未\(AC\)数组,注意我们不在意之前是否\(AC\)
对于3,查找未\(AC\)数组中的没有打过\(AC\)标记的题目,并判断是否输出过,注意只输出前20个即可
(考试的时候没看见,30没了)
其实可以离散化也可以不离散化,看你的\(AC\)标记怎么打,像我的话就是给编号打标记

Code

#include<cstdio>
#include<cstring>
using namespace std;
int m,i,d,now,num,tot,p[105];
long long n,x,hash[10010];
bool b[10010],bj[10010];
int HASH(long long x)
{
    int pos;
    pos=x%10007;
    while (hash[pos]!=0)
    {
        if (hash[pos]==x) return pos;
        pos++;
        if (pos==10007) pos=0;
    }
    hash[pos]=x;
    return pos;
}
int main()
{
    freopen("problem.in","r",stdin);
    freopen("problem.out","w",stdout);
    scanf("%lld%d",&n,&m);
    while (m--)
    {
        scanf("%d",&d);
        if (d==1) 
        {
            scanf("%lld",&x);
            now=HASH(x);
            b[now]=true;
        }
        if (d==2)
        {
            scanf("%lld",&x);
            now=HASH(x);
            if (b[now]==false)
            {
                num++;
                p[num]=now;
            }
        }
        if (d==3)
        {
            memset(bj,false,sizeof(bj));
            tot=0;
            for (i=num;i;i--)
            {
                if (b[p[i]]==false&&bj[p[i]]==false)
                {
                    printf("%lld ",hash[p[i]]);
                    bj[p[i]]=true;
                    tot++;
                }
                if (tot==20) break;
            }
            printf("\n");
        }
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}
posted @ 2020-08-06 14:42  Thunder_S  阅读(105)  评论(0编辑  收藏  举报