1. 程式人生 > 實用技巧 >【NOIP2015模擬11.4】JZOJ8月6日提高組T1 刷題計劃

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