1024 模擬賽

寫在前面

此次模擬賽,難度。。。還能夠吧。由於是歡樂賽,因此打的很開心node

T1序列(sequence)

連接ide

Idea

原本想開個桶的,而後看到了\(a_i \le 10^9\)。因而我就開了個map優化

這算是道模擬題吧。具體看代碼,很好懂的。cy.pngidea

Code

namespace Sol{  
    map<int,int> m;//1e9,不現實 
    int n,tot,t=1,ans=inf,a[1005];//t要從1開始 
    inline int Main(){
        n=read();
        for(int i=1;i<=n;i++){
            a[i]=read();
            if(m[a[i]]==1) tot++;//記錄一個數的個數 
            m[a[i]]++;
        }
        for(int i=1;i<=n;i++){
            m[a[i]]--;
            if(m[a[i]]==1) tot--;
            while(!m[a[t]]&&t<i) m[a[t++]]++;
            if(tot==0) ans=min(ans,i-t+1);
        }
        printf("%d",ans==1?0:ans);//ans=1,表示沒有刪減 
        return 0; 
    }
}

T2數字(number)

連接spa

Idea

一道數學題。找規律便可。code

咱們必定知道,全部數的倍數的個位數是會循環的~~blog

例如:排序

2:2 4:4 6:6 8:8  10:0 12:2 ....  
3:3 6:6 9:9 12:2 15:5 18:8 21:1 24:4 27:7 30:0 33:3......
//以此類推

題目讓求的是 求 \(1 \sim n\) 的全部整數中,能被 \(m\) 整除的整數的個位數字之和 。get

咱們發現了個位數字是循環的,因而咱們就靠這個來優化。數學

發現:當\(x\%10=0\)時 ,\(x\)\(m\)的倍數,一輪循環結束。計算這輪循環的答案\(Ans\)

而後咱們判斷\(1 \sim n\)中有多少個\(x\)。假設有\(a\)個,則這\(a\)組的值爲\(a \times Ans\)

最後計算餘下的數中個位之和便可。講的不是很清,你們本身手玩幾組就知道了。cy.png

能夠藉助代碼理解哦~~

Code

namespace Sol{
    int ans;     
    inline int Main(){
        int T=read();
        while(T--){
            int n=read(),m=read(); ans=0;
            for(int i=m;i<=n;i+=m){
                if(i%10==0){
                    ans*=n/i;//n/i是看有多少組,而後就能夠跳過這n/i組
                    i*=n/i;//跳到了i*=n/i這個數
                }
                ans+=i%10;//計算個位和
            }
            printf("%lld\n",ans);
        }
        return 0; 
    }
}

T3揹包(knapsack)

連接

Idea

knapsack?好奇怪的名字

這道題,是個\(DP\)?仍是我能寫的那種看戲1.jpg

這道題按\(out\)爲第一關鍵字,\(in\)爲第二關鍵字排序。

即先把全部物品按照拿走的時間從小到大排序,拿走的時間相同就按照放上去的時 間從大到小。那麼一件物品上方的物品就必定會在它的前面。

這裏設 \(f[i][j]\)表示\(i\) 以及\(i\) 上面的物品在全部時刻中最大重量爲 \(j\) 時的最 大收益。

轉移的時候,枚舉全部 \(i\) 上面的物品,維護一個 \(g[i]\)表示時刻 \(i\) 以前 物品的最大收益是多少。而後轉移。

目標\(f[n][S]\)

真的很簡單

Code

namespace Sol{  
    struct node{
        int in,out,w,s,v;
    }a[505];
    int f[505][maxn],g[maxn];
    int n,S; 
    inline bool cmp(node a,node b){
        if(a.out==b.out) return a.in>b.in;
        return a.out<b.out;
    }
    inline int Main(){
        n=read(); S=read();
        for(int i=1;i<=n;i++)
            a[i]=(node){read(),read(),read(),read(),read()};
        a[++n]=(node){0,n*2,0,S,0};     
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++)
        for(int w=a[i].w;w<=S;w++){
            int x=a[i].in; g[x]=0;
            int y=min(w-a[i].w,a[i].s);
            for(int j=1;j<i;j++)
            if(a[j].in>=a[i].in){
                while(x<a[j].out)x++,g[x]=g[x-1];
                g[x]=max(g[x],g[a[j].in]+f[j][y]);
            }
            f[i][w]=g[x]+a[i].v;
        }
        printf("%d",f[n][S]);
        return 0; 
    }
}

T4 玩具(toy)

連接

Idea

一道 狀壓又是狀壓,草jwdys.jpg

這裏上題解。由於我太菜了,不會解釋

考慮這個題其實就是給咱們若⼲個⼆進制數,問最終有多少種選數的⽅案使得or(即\(\oplus\)異或)起來所有是1。

\(cnt(S)\)表示等於\(S\)的⼆進制數個數,令\(f(S)=\displaystyle \sum_{S' \subseteq S}cnt(S')\) ,那麼⼀個顯然的容斥有答案爲\(\displaystyle \sum_{S} 2^{f(S)} (-1)^{n-\mid S \mid}\)

因此惟⼀的難點在於怎麼求\(f(S)\),若是直接暴⼒求複雜度是\(3^M\),能夠得到\(70\ pts\)。 這其實就是⼀個⾼維前綴和問題。令\(f_{i,j}\)爲在不考慮前\(i\)位的狀況下,\(j\)的前綴和。 ⾸先,顯然有\(f_{i,j}=cnt_{i}\) ,其次\(f_{i,j}=f_{i+1,j}+f_{j \mid (1<<i)}\),其中\(j\)的第\(i\)位是0. 直接⼀個遞推就作完了

\(\mathcal {P.S:}\)注意爆負。

Code

namespace Sol{  
    int f[maxn],g[maxn],s[maxn],a[maxn];
    inline int Main(){
        int n=read(),m=read();
        a[0]=1;
        for(int i=1;i<=n;i++){
            int x=read();
            for(int j=1;j<=x;j++) s[i]+=(1<<(read()-1));
            g[s[i]]++; a[i]=(a[i-1]<<1)%mod;
        }
        for(int j=0;j<m;j++)
        for(int i=0;i<(1<<m);i++)
        if(i&(1<<j)) g[i]+=g[i-(1<<j)];
        for(int i=0;i<(1<<m);i++)
        f[i]=a[g[i]];
        for(int j=0;j<m;j++)
        for(int i=0;i<(1<<m);i++)
        if(i&(1<<j)) f[i]=((f[i]-f[i-(1<<j)])%mod+mod)%mod;
        printf("%d",f[(1<<m)-1]);
        return 0; 
    }
}

\[ The \quad End \]

\[ \text{我獨酌山外小閣樓,窗外漁火如豆。江畔晚風拂柳,訴盡離愁。當月色暖小樓,是誰又在彈奏那一曲思念常(長)留-《山外小樓夜聽雨》易碩成} \]

相關文章
相關標籤/搜索