2017.5.27 NOIP模拟赛(hzwer2014-5-16 NOIP模拟赛)

期望得分:100+100+60+30=290

实际得分:100+20+60+0=180

当务之急:提高一次正确率

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

自栈顶往下第i个蓝色球,把它变为红色球需要的次数为2^(i-1)

#include<cstdio>
#include<iostream>
using namespace std;
long long ans;
char ch[150];
int main()
{
    int n;
    scanf("%d",&n);
    scanf("%s",ch);
    long long j=1;
    for(int i=0;i<n;i++,j*=2)
     if(ch[i]==‘B‘) ans+=j;
    cout<<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

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char ch[150];
string f[4],b[4],l[4],r[4],u[4],d[4],tmp,tmp2[4];
int main()
{
    scanf("%s",ch+1);
    int len=strlen(ch+1);
    for(int i=1;i<=3;i++)
    {
        cin>>tmp;
        f[i]=‘0‘+tmp;
    }
    for(int i=1;i<=3;i++)
    {
        cin>>tmp;
        b[i]=‘0‘+tmp;
    }
    for(int i=1;i<=3;i++)
    {
        cin>>tmp;
        l[i]=‘0‘+tmp;
    }
    for(int i=1;i<=3;i++)
    {
        cin>>tmp;
        r[i]=‘0‘+tmp;
    }
    for(int i=1;i<=3;i++)
    {
        cin>>tmp;
        u[i]=‘0‘+tmp;
    }
    for(int i=1;i<=3;i++)
    {
        cin>>tmp;
        d[i]=‘0‘+tmp;
    }
    int j;
    for(int i=1;i<=len;i++)
    {
        if(ch[i]==‘2‘)
        {
            for(j=1;j<=3;j++) tmp[j]=f[j][3];
            for(j=1;j<=3;j++) f[j][3]=u[j][3];
            for(j=1;j<=3;j++) u[j][3]=b[j][3];
            for(j=1;j<=3;j++) b[j][3]=d[j][3];
            for(j=1;j<=3;j++) d[j][3]=tmp[j];
            for(j=1;j<=3;j++) tmp2[j]=r[j];
            for(int l=1;l<=3;l++)
             for(int h=1;h<=3;h++)
              r[h][l]=tmp2[l][3-h+1];
        }
        else if(ch[i]==‘1‘)
        {
            for(j=1;j<=3;j++) tmp[j]=f[j][3];
            for(j=1;j<=3;j++) f[j][3]=d[j][3];
            for(j=1;j<=3;j++) d[j][3]=b[j][3];
            for(j=1;j<=3;j++) b[j][3]=u[j][3];
            for(j=1;j<=3;j++) u[j][3]=tmp[j];
            for(j=1;j<=3;j++) tmp2[j]=r[j];
            for(int h=1;h<=3;h++)
             for(int l=1;l<=3;l++)
              r[h][l]=tmp2[3-l+1][h];
        }
        else if(ch[i]==‘3‘)
        {
            tmp=f[1];
            f[1]=l[1];
            l[1]=b[1];
            b[1]=r[1];
            r[1]=tmp;
            for(j=1;j<=3;j++) tmp2[j]=u[j];
            for(int h=1;h<=3;h++)
             for(int l=1;l<=3;l++)
              u[h][l]=tmp2[3-l+1][h];
        }
        else
        {
            tmp=f[1];
            f[1]=r[1];
            r[1]=b[1];
            b[1]=l[1];
            l[1]=tmp;
            for(j=1;j<=3;j++) tmp2[j]=u[j];
            for(int l=1;l<=3;l++)
             for(int h=1;h<=3;h++)
              u[h][l]=tmp2[l][3-h+1];
        }
    }
    int k;
    for(j=1;j<=3;j++)
    {
        for(k=1;k<=3;k++)
          cout<<f[j][k];
        cout<<endl;
    }
    for(j=1;j<=3;j++)
    {
        for(k=1;k<=3;k++)
          cout<<b[j][k];
        cout<<endl;
    }
    for(j=1;j<=3;j++)
    {
        for(k=1;k<=3;k++)
          cout<<l[j][k];
        cout<<endl;
    }
    for(j=1;j<=3;j++)
    {
        for(k=1;k<=3;k++)
          cout<<r[j][k];
        cout<<endl;
    }
    for(j=1;j<=3;j++)
    {
        for(k=1;k<=3;k++)
          cout<<u[j][k];
        cout<<endl;
    }
    for(j=1;j<=3;j++)
    {
        for(k=1;k<=3;k++)
          cout<<d[j][k];
        cout<<endl;
    }
}

第二次愚蠢的错误:复制的时候没有修改

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。

注:此题时限1.5s是因为本评测机跑太慢,大家正常做

但写的太丑可能T一俩个点

60分思路:

f[i][j]表示前i个位置,最后一个位置为第j类的方案数

状态转移:如果j与k能挨在一起 f[i][j]+=+f[i-1][k]

矩阵乘法优化可以满分

系数矩阵就是题目给的01矩阵(0、1反过来)

注意,空位置视作0,0和所有的妹子都可以挨在一起

AC代码:

#include<cstdio>
#define mod 1000000007
using namespace std;
long long v[111][111],tmp[111][111],a[111][111];
char ch[111][111];
int n,m;
long long ans;
void mul(long long s1[111][111],long long s2[111][111])
{
    for(int i=0;i<=m;i++)
     for(int j=0;j<=m;j++)
      for(int k=0;k<=m;k++)
       tmp[i][j]=(tmp[i][j]+s1[i][k]*s2[k][j])%mod;
    for(int i=0;i<=m;i++)
     for(int j=0;j<=m;j++)
      s1[i][j]=tmp[i][j],tmp[i][j]=0;
}
int main()
{
    freopen("harem.in","r",stdin);
    freopen("harem.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
      scanf("%s",ch[i]+1);
    for(int i=1;i<=m;i++)
     for(int j=1;j<=m;j++)
      if(ch[i][j]==‘0‘) v[i][j]=a[i][j]=1;
    for(int i=0;i<=m;i++) v[0][i]=v[i][0]=a[i][0]=a[0][i]=1;
    n--;
    for(;n;n>>=1,mul(v,v))
     if(n&1) mul(a,v);
    for(int i=0;i<=m;i++) ans=(ans+a[i][0])%mod;
    printf("%d",ans);
}

60分代码:

#include<cstdio>
#define mod 1000000007
using namespace std;
int f[511][501];
bool v[501][501];
char ch[501][501];
int main()
{
    freopen("harem.in","r",stdin);
    freopen("harem.out","w",stdout);
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
      scanf("%s",ch[i]+1);
    for(int i=1;i<=m;i++)
     for(int j=1;j<=m;j++)
      if(ch[i][j]==‘1‘) v[i][j]=1;
    f[0][0]=1;
    for(int i=1;i<=n;i++)
     for(int j=0;j<=m;j++)
      {
           for(int k=0;k<=m;k++)
            if(!v[j][k]) f[i][j]=(f[i][j]+f[i-1][k])%mod;
      }
    int ans=0;
    for(int i=0;i<=m;i++) ans=(ans+f[n][i])%mod;
    printf("%d",ans);
}

Problem 4 mex(mex.cpp/c/pas)

【题目描述】

【输入格式】

【输出格式】

【样例输入】

7 5

0 2 1 0 1 3 2

1 3

2 3

1 4

3 6

2 7

【样例输出】

3

0

3

2

4

【样例解释与数据范围】

法一,莫队算法:

#include<cstdio>
#include<cmath>
#include<algorithm>
#define N 200001
using namespace std;
int n,a[N],siz,sum[N],an[N],ans;
struct node
{
    int l,r,bl,id;
}e[N];
inline bool cmp(node p,node q)
{
    if(p.bl!=q.bl) return p.bl<q.bl;
    return p.r<q.r;
}
inline void updata(int pos,int w,int g)
{
    sum[a[pos]]+=w;
    if(g==1&&a[pos]==ans)  while(sum[ans]) ans++;
    if(g==2&&a[pos]<ans&&!sum[a[pos]])  ans=a[pos];
}
inline int read()
{
    int x=0; char c=getchar();
    while(c<‘0‘||c>‘9‘) c=getchar();
    while(c>=‘0‘&&c<=‘9‘) { x=x*10+c-‘0‘; c=getchar();}
    return x;
}
void out(int x)
{
    if(x/10) out(x/10);
    putchar(x%10+‘0‘);
}
int main()
{
    freopen("mex.in","r",stdin);
    freopen("mex.out","w",stdout);
    int q;
    n=read(); q=read();
    siz=sqrt(n)*1.5;
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<=q;i++)
    {
        e[i].l=read(); e[i].r=read();
        e[i].bl=(e[i].l-1)/siz+1;
        e[i].id=i;
    }
    sort(e+1,e+q+1,cmp);
    int opl,opr,l=1,r=0;
    for(int i=1;i<=q;i++)
    {
        opl=e[i].l; opr=e[i].r;
        while(opl<l) updata(--l,1,1);
        while(opr>r) updata(++r,1,1);
        while(opl>l) updata(l++,-1,2);
        while(opr<r) updata(r--,-1,2);
        an[e[i].id]=ans;
    }
    for(int i=1;i<=q;i++)
     {
         out(an[i]);
         puts("");
     }
}

法二,主席树(用时是莫队的一半)

以权值为下标,

minn[i]=j,表示i所代表的权值为[l,r]的区间,最早出现的位置为j

例:0 2 1 0 1 3 2

对于root[7]来说,

[0,3]=1, 0最早出现在第1个位置

[1,3]=2, 2最早出现在第2个位置

查询[l,r]时,在root[r]里查询

如果左子区间的minn>=l,说明权值小的左边一半都最早出现在l以后,就往右孩子找

否则,说明权值小的左边一半有没有出现在l之后的,就往左孩子找

因为是在root[r]里,所以保证不超过右边界

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200001
using namespace std;
int n,q,tot;
int root[N],minn[N*20];

    int lc[N*20],rc[N*20];
    void change(int &now,int pre,int l,int r,int pos,int val)
    {
        if(!now) now=++tot;
        if(l==r)
        {
            minn[now]=val;
            return;
        }
        int mid=l+r>>1;
        if(pos<=mid)
        {
            change(lc[now],lc[pre],l,mid,pos,val);
            rc[now]=rc[pre];
        }
        else
        {
            change(rc[now],rc[pre],mid+1,r,pos,val);
            lc[now]=lc[pre];
        }
        minn[now]=min(minn[lc[now]],minn[rc[now]]);
    }
    int query(int now,int l,int r,int pos)
    {
        if(l==r) return l;
        int mid=l+r>>1;
        if(minn[lc[now]]>=pos) return query(rc[now],mid+1,r,pos);
        return query(lc[now],l,mid,pos);
    }

int main()
{
    freopen("mex.in","r",stdin);
    freopen("mex.out","w",stdout);
    int m;
    scanf("%d%d",&n,&m);
    int x;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        if(x>n) x=n;
        change(root[i],root[i-1],0,n,x,i);
    }
    int l,r;
    while(m--)
    {
        scanf("%d%d",&l,&r);
        printf("%d\n",query(root[r],0,n,l));
    }
}

时间: 2024-10-27 03:19:59

2017.5.27 NOIP模拟赛(hzwer2014-5-16 NOIP模拟赛)的相关文章

[2012山东ACM省赛] n a^o7 !(模拟,字符替换)

n a^o7 ! Time Limit: 1000MS Memory limit: 65536K 题目描述 All brave and intelligent fighters, next you will step into a distinctive battleground which is full of sweet and happiness. If you want to win the battle, you must do warm-up according to my inst

【第三组】冲刺会议 2017.7.27

冲刺会议 日期:2017.7.27 开发小组:Geomestry 冲刺经理:程立智 成员: 程立智 李明伦 郑昊 蔡镇泽 温志成 汪涵 成员:程立智 完成工作:实现多语言在app内即时切换,继续解决bug 所遇问题: 语言在app内即时切换时第一次点击没反应(已解决) 下一步工作: 继续实现各种界面的细节和前后端的联系,解决大家遇到的各种系统bug 成员:李明伦 完成工作:设计关卡内容 所遇问题:胜利条件不好写 下一步工作:继续设计关卡内容 成员:郑昊 完成工作:做主界面图片,option自适应

acm集训训练赛B题【排序+模拟】

一.原题 Description Being a programmer, you like arrays a lot. For your birthday, your friends have given you an array a consisting of ndistinct integers. Unfortunately, the size of a is too small. You want a bigger array! Your friends agree to give you

柴赛特刊丨访第16届“柴赛”钢琴组评委会主席-丹尼斯&#183;马祖耶夫

对话“柴赛”大师 备受全球音乐圈和爱乐者高度关注的第16届柴可夫斯基国际音乐比赛(简称“柴赛”)完美落下帷幕.比赛期间,作为第16届“柴赛”钢琴组评委会主席的Denis Matsuev(丹尼斯·马祖耶夫)接受了CCTV.中新社.中俄资讯网等多家媒体的联合采访.这位享誉世界的“钢琴大师”畅所欲言,讲述只属于本届柴可夫斯基钢琴大赛的精彩故事. 谈柴可夫斯基钢琴大赛独有特色 议中国选手大赛表现 评指定用琴中国“长江钢琴” 丹尼斯·马祖耶夫畅所欲言 全面解析本届柴可夫斯基钢琴大赛 精彩阐述对钢琴艺术的独

2017 9 27 模拟赛T1

题意简述: 求1-n中所有数的k次方的和,答案对1234567891取模. 样例输入格式: 一行,两个整数n,k 样例输出格式: 一个整数,即所求的和. 数据范围:n<10^9,k<100 这道题n非常大,即使是O(n)的算法也不能承受,但是此题的k却非常小,这也就提醒由k入手. 首先预处理前k+1个数的k次方的和,如果n<=k+1的话其实就可以直接输出a[0][n]了,不过我觉得出题人不会出这样的数据. 为什么是k+1个数呢?这是为了能处理一些差分的问题. 然后不断地计算每一行的差分,

2017 9 27 模拟赛 T2

原题题意:给出一个集合S,现满足以下关系: 实际题意:求32的n次方(这...)

2017.9.10所谓“切题如切菜杯”水题模拟赛(;&#180;д`)ゞ

T1:MHM LGL今天一共要上n节课,这n节课由0标号至n.由于过度劳累,除了第0节课和第n节课,LGL还打算睡上m节课,所以他做了一个睡觉计划表.通过小道消息,LGL得知WQ今天会在学校中检查,所以他想少睡k节课.但是由于某些原因,他又想使相邻的两节睡觉的课之间上的课数量的最小值最大.由于他很困,所以他请你来帮他计算这个值.   输入格式: 第一行为三个整数 n.m.k,接下来的m行为m个整数ai,表示睡觉计划表中LGL想要睡觉的课. 输出格式: 一个整数,表示题目所求的值. 样例输入 样例

关于10月16日模拟赛的心得与感悟

终于写到今天了... 第一题:纯水题,送分.模拟即可 第二题:最短路径. 大概题意是给出两个点的编号和n个点的坐标.要求每个点经过一次,0点允许经过两次.其中有三个限制条件: 1.从A走到B时,只能由横坐标小的点走到大的点.2.由B回到A时,只能由横坐标大的点走到小的点.3.有两个特殊点b1和b2,b1在0到n-1的路上,b2在n-1到0的路上. 可以运用动规的思想,定义dp[i][j].表示了第一条线路最前端为i , 第二条线路最前端为j 的最小路径长度. 每次更新时,取出 k = max(

hdu 5475 模拟计算器乘除 (2015上海网赛F题 线段树)

给出有多少次操作 和MOD 初始值为1 操作1 y 表示乘上y操作2 y 表示除以第 y次操作乘的那个数 线段树的叶子结点i 表示 第i次操作乘的数 将1替换成y遇到操作2 就把第i个结点的值 替换成1利用线段树的性质,对整个1~n的区间进行维护,每次输出sum[1]的值即可 Sample Input110 10000000001 22 11 21 102 32 41 61 71 122 7 Sample OutputCase #1:2122010164250484 1 # include <i