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

【样例解释】

样例1:

样例2:

【数据范围】

50%的数据,1<=n<=20

100%的数据,1<=n<=50

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

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一俩个点

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

【样例解释与数据范围】


T1:

这题一开始看数据范围这么小,于是乎直接模拟,T5个点

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define MAXN 55
using namespace std;
int stack[MAXN],top=;
int cnt;
int n;
int ans=;
int main()
{
scanf("%d",&n);
// 1 red 2 blue;
for(int i=n;i>=;i--){
char c;
scanf(" %c",&c);
if('R'==c){
stack[i]=;
cnt++;
}
else{
stack[i]=;
}
}
top=n;
while(){
ans++;
while(==stack[top]&&top){
top--;
cnt--;
}
if(==stack[top]&&top){
stack[top]=;
cnt++;
}
for(int i=top+;i<=n;i++){
stack[i]=;
}
top=n;
if(cnt==n){
break;
}
}
printf("%d\n",ans);
return ;
}

Code1

后来发现其实是找规律的:

对于一个栈,我们只考虑从栈顶到第一个blue,即RRRRB,因为所有操作不可能干到这个B底下,

我们姑且无视B下面的东西吧

然后发现操作1次为BBBBR,再次无视这个R,变成了BBBB

然后发现操作分别变成RBBB BRBB RRBB ……

如同0000 1000 0100 1100 ……

规律出来了,对于栈中自上向下第i个B,把它变成R需要2^(i-1),然后依次处理即可

注意:用long long的时候就不可以把int类型的i直接(1<<(i-1)),会炸的

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
int n;
ll ans;
ll Power(int p){
ll ret=;
for(int i=;i<=p;i++){
ret*=;
}
return ret;
}
int main()
{
char c;
scanf("%d",&n);
for(int i=;i<n;i++){
scanf(" %c",&c);
if('B'==c){
ans+=Power(i);
}
}
printf("%lld\n",ans);
return ;
}

Code2


T2:

这题可以用一些技巧,比如操作2等价于操作1三次,

左旋一次等价于右旋三次等等

另外传址的函数可以在很大程度上简化程序

拼的是基本功啊

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#define REP(x,y) for(int x=1;x<=y;x++)
using namespace std;
void move(int s1[][],int s2[][],int s3[][],int s4[][],int x1,int y1,int x2,int y2){
int t[][]={};
memcpy(t,s1,sizeof(t));
for(int i=x1;i<=x2;i++){
for(int j=y1;j<=y2;j++){
s1[i][j]=s2[i][j];
s2[i][j]=s3[i][j];
s3[i][j]=s4[i][j];
s4[i][j]=t[i][j];
}
}
}
void Lx(int ss[][]){
int t[][]={};
for(int i=;i<=;i++){
t[i][]=ss[][-i];
t[][i]=ss[i][];
t[i][]=ss[][-i];
t[][i]=ss[i][];
}
t[][]=ss[][];
for(int i=;i<=;i++){
for(int j=;j<=;j++){
ss[i][j]=t[i][j];
}
}
}
void Rx(int ss[][]){
Lx(ss),Lx(ss),Lx(ss);
}
int s[][][];
char c[];
void P2(){
//1qian 2hou 3zuo 4you 5shang 6xia
move(s[],s[],s[],s[],,,,);
Lx(s[]);
}
void P1(){
P2(),P2(),P2();
}
void P3(){
//1qian 2hou 3zuo 4you 5shang 6xia
move(s[],s[],s[],s[],,,,);
Rx(s[]);
}
void P4(){
P3(),P3(),P3();
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("my.out","w",stdout);
scanf("%s",c+); REP(k,){
REP(i,){
char p[]={};
scanf("%s",p+);
REP(j,){
s[k][i][j]=p[j]-'';
}
}
}
int len=strlen(c+);
for(int p=;p<=len;p++){ if(''==c[p]){
P1();
}
else if(''==c[p]){
P2();
}
else if(''==c[p]){
P3();
}
else{
P4();
}
//printf("p=%d\n",p);
//REP(k,6){
// printf("k=%d\n",k);
// REP(i,3){
// REP(j,3){
// printf("%d",s[k][i][j]);
// }
// printf("\n");
// }
// printf("\n");
//}
} REP(k,) REP(i,){
REP(j,){
printf("%d",s[k][i][j]);
}
printf("\n");
}
return ;
}

Code6


T3:

设f[i][j]表示i个座位,必须以第j个妹子为结尾的方案

然后f[i][j]=∑f[i-1][k] (j,k不矛盾)

当然矩阵快速幂优化即可,详见代码

注意:

1,妹子可以为空,那么直接m++即可,多出来的矩阵用1补足

2,输入的01矩阵和转移矩阵正好反的

3,对于矩阵较大的内存,最好不要用递归快速幂,直接用循环即可

4,切记要开long long!!!

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<iostream>
#define MAXN 105
#define MOD 1000000007
#define ll long long
using namespace std;
struct Mat{
int len;
ll s[MAXN][MAXN];
Mat(){
len=;
memset(s,,sizeof(s));
}
void operator *= (const Mat &A){
Mat t;
len=A.len;
for(int i=;i<=len;i++){
for(int j=;j<=len;j++){
for(int k=;k<=len;k++){
t.s[i][j]=(t.s[i][j]+(s[i][k]*A.s[k][j])%MOD)%MOD;
}
}
}
for(int i=;i<=len;i++){
for(int j=;j<=len;j++){
s[i][j]=t.s[i][j];
}
}
}
void operator = (const Mat &A){
len=A.len;
for(int i=;i<=len;i++){
for(int j=;j<=len;j++){
s[i][j]=A.s[i][j];
}
}
}
};
int n,m;
Mat Power(Mat A,int p){
Mat ret;
ret.len=m+;
for(int i=;i<=ret.len;i++){
ret.s[i][i]=;
}
Mat t; t=A;
for(;p;p>>=){
if(p&){
ret*=t;
}
t*=t;
}
return ret;
}
int main()
{
// freopen("harem2.in","r",stdin);
Mat A;
scanf("%d%d",&n,&m);
if(==n){
printf("%d\n",m+);
}
char ch[MAXN]={};
for(int i=;i<=m;i++){
scanf("%s",ch+);
for(int j=;j<=m;j++){
if(''==ch[j])
A.s[i][j]=;
}
}
A.len=m+;
for(int i=;i<=m+;i++){
A.s[m+][i]=A.s[i][m+]=;
}
Mat t=Power(A,n-);
ll ans=;
int len=t.len;
for(int i=;i<=len;i++){
for(int j=;j<=len;j++){
ans=(ans+t.s[i][j])%MOD;
}
}
cout<<ans<<endl;
return ;
}

Code3


T4:

我当时用莫队算法+暴力,60分

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#define MAXN 200005
using namespace std;
struct Ask{
int L,R;
int lb,id;
int ans;
Ask(){
L=R=lb=ans=;
}
};
bool comp1(const Ask &p1,const Ask &p2){
if(p1.lb!=p2.lb){
return (p1.lb<p2.lb);
}
else{
return (p1.R<p2.R);
}
}
bool comp2(const Ask &p1,const Ask &p2){
return (p1.id<p2.id);
}
Ask s[MAXN];
int n,T;
int b[MAXN];
int a[MAXN];
int main()
{
// freopen("data.in","r",stdin);
scanf("%d%d",&n,&T);
int size=sqrt(n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=;i<=T;i++){
scanf("%d%d",&s[i].L,&s[i].R);
s[i].lb=s[i].L/size;
s[i].id=i;
}
sort(s+,s+T+,comp1);
int x=,y=;
int t=;
for(int i=;i<=T;i++){
int L=s[i].L,R=s[i].R;
if(x<L){
for(int j=x;j<L;j++){
b[a[j]]--;
if(!b[a[j]]){
t=min(t,a[j]);
}
}
}
else if(x>L){
for(int j=x-;j>=L;j--){
if(!b[a[j]]&&t==a[j]){
for(t++;;t++){
if(!b[t]){
break;
}
}
}
b[a[j]]++;
}
}
if(y<R){
for(int j=y+;j<=R;j++){
if(!b[a[j]]&&t==a[j]){
for(t++;;t++){
if(!b[t]){
break;
}
}
}
b[a[j]]++;
}
}
else if(y>R){
for(int j=y;j>R;j--){
b[a[j]]--;
if(!b[a[j]]){
t=min(t,a[j]);
}
}
}
x=L,y=R;
s[i].ans=t;
}
sort(s+,s+T+,comp2);
for(int i=;i<=T;i++){
printf("%d\n",s[i].ans);
}
return ;
}

Code4

其实这题并不好写,原因这些数据都是离散的,搞不出来连续的,用数据结构不好维护

于是可以构造出连续的数据:Next[i]=j (a[i]==a[j]&&i<j)

然后按左节点从左到右依次解决,当左节点变化时,相应的j~Next[j]-1用线段树进行更新即可

这样可以用离线算法解决了,转化为典型的离线问题

另:线段树切记开4倍啊QAQ

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define MAXN 200005
#define INF 0x7f7f7f7f
using namespace std;
int mex[MAXN];
int n,m;
int dat[MAXN*],tag[MAXN*]; void build(int k,int L,int R){
//build:L+1==R return
if(L+==R){
dat[k]=mex[L];
return ;
}
build(k<<,L,(L+R)>>);
build(k<<|,(L+R)>>,R);
}
void pushdown(int k){
int lc=(k<<),rc=(k<<|);
dat[lc]=min(dat[lc],tag[k]);
dat[rc]=min(dat[rc],tag[k]);
tag[lc]=min(tag[lc],tag[k]);
tag[rc]=min(tag[rc],tag[k]);
tag[k]=INF;
}
void update(int a,int b,int k,int L,int R,int t){
if(b<=L||R<=a){
return;
}
else if(a<=L&&R<=b){
dat[k]=min(dat[k],t);
tag[k]=min(tag[k],t);
}
else{
if(tag[k]!=INF){
pushdown(k);
}
update(a,b,k<<,L,(L+R)>>,t);
update(a,b,k<<|,(L+R)>>,R,t);
}
}
int find(int x,int k,int L,int R){
if(L+==R){
return dat[k];
}
int mid=(L+R)>>;
if(tag[k]!=INF){
pushdown(k);
}
if(x<mid){
return find(x,k<<,L,mid);
}
else{
return find(x,k<<|,mid,R);
}
}
struct Ask{
int L,R;
int id,ans;
Ask(){
L=R=id=ans=;
}
}s[MAXN];
bool comp1(const Ask &p1,const Ask &p2){
return (p1.L<p2.L);
}
bool comp2(const Ask &p1,const Ask &p2){
return (p1.id<p2.id);
}
int a[MAXN],b[MAXN];
int Next[MAXN],first[MAXN]; int main()
{
// freopen("T1.in","r",stdin);
// freopen("my.out","w",stdout);
memset(dat,0x7f,sizeof(dat));
memset(tag,0x7f,sizeof(tag));
// freopen("data.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=;i<=m;i++){
scanf("%d%d",&s[i].L,&s[i].R);
s[i].id=i;
}
int k=;
for(int i=;i<=n;i++){
b[a[i]]=;
while(b[k]){
k++;
}
mex[i]=k;
}
build(,,n+);
for(int i=n;i>=;i--){
Next[i]=first[a[i]];
first[a[i]]=i;
if(!Next[i]){
Next[i]=n+;
}
}
sort(s+,s+m+,comp1);
int nL=;
for(int i=;i<=m;i++){
if(nL<s[i].L){
for(int j=nL;j<s[i].L;j++){
update(j,Next[j]-+,,,n+,a[j]);
}
nL=s[i].L;
}
// for(int j=1;j<=n;j++){
// printf("%d ",find(j,1,1,n+1));
// }
// printf("\n");
s[i].ans=find(s[i].R,,,n+);
}
sort(s+,s+m+,comp2);
for(int i=;i<=m;i++){
printf("%d\n",s[i].ans);
}
return ;
}

Code5

NOIP2014-5-17模拟赛的更多相关文章

  1. 11.17 模拟赛&&day-2

    /* 后天就要复赛了啊啊啊啊啊. 可能是因为我是一个比较念旧的人吧. 讲真 还真是有点不舍. 转眼间一年的时间就过去了. 2015.12-2016.11. OI的一年. NOIP gryz RP++. ...

  2. 10.17 NOIP模拟赛

    目录 2018.10.17 NOIP模拟赛 A 咒语curse B 神光light(二分 DP) C 迷宫maze(次短路) 考试代码 B 2018.10.17 NOIP模拟赛 时间:1h15min( ...

  3. EZ 2018 06 17 NOIP2018 模拟赛(十九)

    这次的题目难得的水,但是由于许多哲学的原因,第二题题意表述很迷. 然后是真的猜题意了搞了. 不过这样都可以涨Rating我也是服了. Upt:链接莫名又消失了 A. 「NOIP2017模拟赛11.03 ...

  4. 10.17(山东多校联合模拟赛 day1)

    山东多校联合模拟赛 day1 题不难 rect [问题描述] 给出圆周上的 N 个点, 请你计算出以这些点中的任意四个为四个角,能构成多少个矩形. 点的坐标是这样描述的, 给定一个数组 v[1..N] ...

  5. NOIP模拟赛 17.10.10

    初次见面(firstmeet)[题目背景]雾之湖边,静得可怕.露米娅出神凝望.黑白连衣裙,像极了绽放的墨黑和洁白的莲.身边的雾之湖,倒映着血色天空.酒红的双眸,映照一切.低声浅笑,双臂伸直,她悄无声息 ...

  6. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  7. 小奇模拟赛9.13 by hzwer

    2015年9月13日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿(explo) [题目背景] 小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值w)的飞船,按既定路线依次飞 ...

  8. 【20170521校内模拟赛】热爱生活的小Z

    学长FallDream所出的模拟赛,个人感觉题目难度还是比较适中的,难度在提高+左右,可能比较接近弱省省选,总体来讲试题考查范围较广,个人认为还是很不错的. 所有试题如无特殊声明,开启-O2优化,时限 ...

  9. 52-2018 蓝桥杯省赛 B 组模拟赛(一)java

    最近蒜头君喜欢上了U型数字,所谓U型数字,就是这个数字的每一位先严格单调递减,后严格单调递增.比如 212212 就是一个U型数字,但是 333333, 9898, 567567, 313133131 ...

  10. NOI.AC NOIP模拟赛 第五场 游记

    NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...

随机推荐

  1. 201621123062《java程序设计》第三周作业总结

    1.本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用 将这些碎片化的概念.知识点组织起来.请使用工具画出本周学习到的知识点及知识点之间的联系.步骤如下: 1.1写出你认为本周学 ...

  2. C语言博客作业--字符数组-陈张鑫

    一.PTA实验作业(4分) 题目1:7-5 查验身份证 1. 本题PTA提交列表(要提交列表,不是结果) 2. 设计思路(伪代码或流程图) 定义变量身份证个数n,合法个数count=0,flag=0, ...

  3. Trie树(转)

    原文http://www.cnblogs.com/TheRoadToTheGold/p/6290732.html 一.引入 字典是干啥的?查找字的. 字典树自然也是起查找作用的.查找的是啥?单词. 看 ...

  4. js判断flash文件是否加载完毕

    轮询判断加载进度 img的加载完成有onload方法,一直不知道该怎么判断swf文件是否加载完毕了? 在应用中使用了轮询判断加载进度值PercentLoaded是否达到100,经测试,可以达到效果. ...

  5. zookeeper 入门系列-理论基础 – zab 协议

    上一章讨论了paxos算法,把paxos推到一个很高的位置.但是,paxos有没有什么问题呢?实际上,paxos还是有其自身的缺点的: 1. 活锁问题.在base-paxos算法中,不存在leader ...

  6. JAVA_SE基础——39.继承

    在面向对象程序设计中,可以从已有的类派生出新类. 这称做继承(inheritance). 白话解释: 例子1:继承一般是指晚辈从父辈那里继承财产,也可以说是子女拥有父母给予他们的东西. 例子2:猫和狗 ...

  7. JQ 上传文件(单个,多个,分片)

    最原始的方式: 前端代码: <div> <span>最原始的方式</span><br /> <span>条件1:必须是 post 方式< ...

  8. split 过滤空的元素

    命令形式: split(str='',number=string.count(str))[n] str 分隔符 number 切分几次,[n] 获取第几个值. 1.如果切分的可迭代对象中包含空元素的解 ...

  9. spring3——IOC之基于XML的依赖注入(DI )

    我们知道spring容器的作用是负责对象的创建和对象间关系的维护,在上一篇博客中我们讲到spring容器会先调用对象的无参构造方法创建一个空值对象,那么接下来容器就会对对象的属性进行初始化,这个初始化 ...

  10. PV 动态供给 - 每天5分钟玩转 Docker 容器技术(153)

    前面的例子中,我们提前创建了 PV,然后通过 PVC 申请 PV 并在 Pod 中使用,这种方式叫做静态供给(Static Provision). 与之对应的是动态供给(Dynamical Provi ...