NOIP模擬賽20161023

Candy?發表於2016-10-23

題目名

雙色球

魔方

czy的後宮

mex

原始檔

ball.cpp/c/pas

cube.cpp/c/pas

harem.cpp/c/pas

mex.cpp/c/pas

輸入檔案

ball.in

cube.in

harem.in

mex.in

輸出檔案

ball.out

cube.out

harem.out

mex.out

時間限制

1000MS

1000MS

1500MS

1000MS

記憶體限制

256MB

256MB

256MB

256MB

測試點

10

10

10

10

測試點分值

10

10

10

10


 

Problem 1 雙色球(ball.cpp/c/pas)

【題目描述】

    機房來了新一屆的學弟學妹,邪惡的chenzeyu97發現一位學弟與他同名,於是他當起了善良的學長233

“來來來,學弟,我考你道水題檢驗一下你的水平……”

一個棧內初始有n個紅色和藍色的小球,請你按照以下規則進行操作

  1. 只要棧頂的小球是紅色的,將其取出,直到棧頂的球是藍色
  2. 然後將棧頂的藍球變成紅色
  3. 最後放入若干個藍球直到棧中的球數為n

以上3步驟為一次操作

如棧中都是紅色球,則操作停止,請問幾次操作後停止

chenzeyu97出完題發現他自己不能AC所以想請你幫忙

【輸入格式】

第一行為一個整數n,表示棧的容量為n

第二行為一個字串,第i個字元表示自頂向下的第i個球的顏色,R代表紅色,B代表藍色

【輸出格式】

一個整數表示運算元

【樣例輸入】

樣例1:

3

RBR

樣例2:

4

RBBR

【樣例輸出】

樣例1:2

樣例2:6

【資料範圍】

50%的資料,1<=n<=20

100%的資料,1<=n<=50


 

模擬,複雜度好像會爆炸

發現一個藍色變成紅色,它前面必須全是紅色

考慮全藍色的情況f[i]=2*f[i-1]+1,就是漢諾塔

這樣從前往後掃,每個藍色帶來的運算元就是f[i]-f[i-1](因為前面已經是紅色了,一個f[i-1]不用了)

PS:灰哥的找規律做法,每個位置變藍的運算元1,2,4,8,16.........

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=55;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,a[N],p=0;
ll f[N];
char s[N];
int main(int argc, const char * argv[]){
    freopen("ball.in","r",stdin);
    freopen("ball.out","w",stdout);
    
    n=read();
    scanf("%s",s+1);
    for(int i=1;i<=n;i++) a[i]= s[i]=='R'?1:0;
    for(int i=1;i<=n;i++) f[i]=2*f[i-1]+1;
    ll ans=0;
    for(int i=1;i<=n;i++)
        if(a[i]==0) ans+=f[i]-f[i-1];
    printf("%lld",ans);
}



 

Problem 2 魔方(cube.cpp/c/pas)

【題目描述】

ccy(ndsf)覺得手動復原魔方太慢了,所以他要藉助計算機。

ccy(ndsf)家的魔方都是3*3*3的三階魔方,大家應該都見過。



3的“順時針”改為“逆時針”,即3 4以圖為準。)
ccy(ndfs)從網上搜了一篇攻略,並找人翻譯成了他自己會做的方法。現在告訴你他的魔方情況,以及他從網上搜到的攻略,請你求出最後魔方變成什麼樣子。

【輸入格式】
   第一行,一串數字,表示從網上搜到的攻略。
   下面6*3行,每行3個數字,每三行表示魔方一個面的情況,六個面的順序是前、後、左、右、上、下。

【輸出格式】
   6*3行,表示處理後的魔方,形式同輸入。

【樣例輸入】

23
121
221
111
123
321
111
123
321
132
132
231
132
121
112
233
332
111
333

【樣例輸出】

123
222
113
212
321
113
122
321
132
121
333
121
211
312
113
331
111
331

【樣例解釋】

 

【資料範圍】

40%的資料,攻略的長度小於5且僅有4種操作的其中一種

100%的資料,攻略的長度小於100


 洛谷2007

 

大模擬

注意每個圖的方向很奇葩,參考樣例

樣例和資料有點問題,頂部的順時針和逆時針旋轉顛倒了,按著錯誤來就過了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=105;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,s[N],a[7][4][4],b[4];
char tmp[N],t[7][4][4];
void cpy(int x[4][4],int y[4][4]){
    for(int i=1;i<=3;i++)
        for(int j=1;j<=3;j++) y[i][j]=x[i][j];
}
void rot(int p,int d){//1 shun  2 ni
    int na[4][4];
    cpy(a[p],na);
    if(d==1){
        for(int i=1;i<=3;i++)    b[i]=na[1][i];
        for(int i=1;i<=3;i++)    a[p][1][i]=na[3-i+1][1];
        for(int i=1;i<=3;i++)    a[p][i][1]=na[3][i];
        for(int i=1;i<=3;i++)    a[p][3][i]=na[3-i+1][3];
        for(int i=1;i<=3;i++)    a[p][i][3]=b[i];
    }else{
        for(int i=1;i<=3;i++)    b[i]=na[1][i];
        for(int i=1;i<=3;i++)    a[p][1][i]=na[i][3];
        for(int i=1;i<=3;i++)    a[p][i][3]=na[3][3-i+1];
        for(int i=1;i<=3;i++)    a[p][3][i]=na[i][1];
        for(int i=1;i<=3;i++)    a[p][i][1]=b[3-i+1];
    }
}
void sol(int flag){
    if(flag==1){
        for(int i=1;i<=3;i++){
            b[i]=a[1][i][3];
            a[1][i][3]=a[6][i][3];
            a[6][i][3]=a[2][i][3];
            a[2][i][3]=a[5][i][3];
            a[5][i][3]=b[i];
        }
        rot(4,1);
    }else if(flag==2){
        for(int i=1;i<=3;i++){
            b[i]=a[1][i][3];
            a[1][i][3]=a[5][i][3];
            a[5][i][3]=a[2][i][3];
            a[2][i][3]=a[6][i][3];
            a[6][i][3]=b[i];
        }
        rot(4,2);
    }else if(flag==3){
        for(int i=1;i<=3;i++){
            b[i]=a[1][1][i];
            a[1][1][i]=a[3][1][i];
            a[3][1][i]=a[2][1][i];
            a[2][1][i]=a[4][1][i];
            a[4][1][i]=b[i];
        }
        //rot(5,2); right
        rot(5,1);
    }else if(flag==4){
        for(int i=1;i<=3;i++){
            b[i]=a[1][1][i];
            a[1][1][i]=a[4][1][i];
            a[4][1][i]=a[2][1][i];
            a[2][1][i]=a[3][1][i];
            a[3][1][i]=b[i];
        }
        //rot(5,1); right
        rot(5,2);
    }
    
    
//    for(int i=1;i<=6;i++)
//        for(int j=1;j<=3;j++){
//            for(int k=1;k<=3;k++)
//                printf("%d",a[i][j][k]);
//            putchar('\n');
//        }
//        printf("\n\n\n");
}
int main(int argc, const char * argv[]){
    freopen("cube.in","r",stdin);
    freopen("cube.out","w",stdout);
    scanf("%s",tmp+1);
    int n=strlen(tmp+1);
    for(int i=1;i<=n;i++) s[i]=tmp[i]-'0';
    for(int i=1;i<=6;i++)
        for(int j=1;j<=3;j++){
            scanf("%s",t[i][j]+1);
            int len=strlen(t[i][j]+1);
            for(int k=1;k<=len;k++) a[i][j][k]=t[i][j][k]-'0';
        }
    for(int i=1;i<=n;i++) sol(s[i]);
    for(int i=1;i<=6;i++)
        for(int j=1;j<=3;j++){
            for(int k=1;k<=3;k++)
                printf("%d",a[i][j][k]);
            putchar('\n');
        }
    
}



 

Problem 3 czy的後宮(harem.cpp/c/pas)

【題目描述】

czy要妥善安排他的後宮,他想在機房擺一群妹子,一共有n個位置排成一排,每個位置可以擺妹子也可以不擺妹子。有些型別妹子如果擺在相鄰的位置(隔著一個空的位置不算相鄰),就不好看了。假定每種妹子數量無限,求擺妹子的方案數。

【輸入格式】

輸入有m+1行,第一行有兩個用空格隔開的正整數n、m,m表示妹子的種類數。接下來的m行,每行有m個字元1或0,若第i行第j列為1,則表示第i種妹子第j種妹子不能排在相鄰的位置,輸入保證對稱。(提示:同一種妹子可能不能排在相鄰位置)。

【輸出格式】

輸出只有一個整數,為方案數(這個數字可能很大,請輸出方案數除以1000000007的餘數。

【樣例輸入】

2 2

01

10

【樣例輸出】

7

【樣例說明】

七種方案為(空,空)、(空,1)、(1、空)、(2、空)、(空、2)、(1,1)、(2,2)。

【資料範圍】

20%的資料,1<n≤5,0<m≤10。

60%的資料,1<n≤200,0<m≤100。

100%的資料,1<n≤1000000000,0<m≤100。


 ch30 擺花

 

一眼看出正解:矩陣乘法加速DP

然後已忘記矩陣乘法

就打了個裸DP加滾動陣列加卡常,還是60

f[i][j]前i個mz以j結尾

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int M=105,MOD=1000000007;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,m,g[M][M];
ll f[2][M],p=0;
char s[M];
inline void mod(ll &x){if(x>=MOD) x-=MOD;}
void dp(){
    for(int j=0;j<=m;j++) f[p][j]=1;
    for(int i=2;i<=n;i++){
        p^=1;
        for(int j=0;j<=m;j++){
            f[p][j]=0;
            for(int k=0;k<=m;k++) if(g[j][k]){
                f[p][j]+=f[p^1][k];
                mod(f[p][j]);
            }
        }
    }
}

int main(int argc, const char * argv[]){
    freopen("harem.in","r",stdin);
    freopen("harem.out","w",stdout);

    n=read();m=read();
    for(int i=1;i<=m;i++){
        scanf("%s",s+1);
        for(int j=1;j<=m;j++) g[i][j]=(s[j]-'0')^1;
    }
    for(int i=0;i<=m;i++) g[i][0]=g[0][i]=1;
    dp();
    ll ans=0;
    for(int i=0;i<=m;i++) ans=(ans+f[p][i])%MOD;
    printf("%lld",ans);

} 

正解

http://www.cnblogs.com/candy99/p/5991535.html

 




mex

我靠不是bzoj那道嘛

果斷30分暴力