9.2noip模拟试题

 


题目名称


改造二叉树


数字对


交换


英文名称


binary


pair


swap


输入文件名


binary.in


pair.in


swap.in


输出文件名


binary.out


pair.out


swap.out


时间限制


1s


2s


1s


空间限制


256M


256M


256M


测试点数目


20


20


10


测试点分值


5


5


10


是否有部分分





题目类型


传统


传统


传统


是否有SPJ




1.改造二叉树

【题目描述】

小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树。通常子结点被称作“左孩子”和“右孩子”。二叉树被用作二叉搜索树和二叉堆。随后他又和他人讨论起了二叉搜索树。

什么是二叉搜索树呢?二叉搜索树首先是一棵二叉树。设key[p]表示结点p上的数值。对于其中的每个结点p,若其存在左孩子lch,则key[p]>key[lch];若其存在右孩子rch,则key[p]<key[rch];注意,本题中的二叉搜索树应满足对于所有结点,其左子树中的key小于当前结点的key,其右子树中的key大于当前结点的key。

小Y与他人讨论的内容则是,现在给定一棵二叉树,可以任意修改结点的数值。修改一个结点的数值算作一次修改,且这个结点不能再被修改。若要将其变成一棵二叉搜索树,且任意时刻结点的数值必须是整数(可以是负整数或0),所要的最少修改次数。

相信这一定难不倒你!请帮助小Y解决这个问题吧。

【输入格式】

第一行一个正整数n表示二叉树结点数。结点从1~n进行编号。

第二行n个正整数用空格分隔开,第i个数ai表示结点i的原始数值。

此后n - 1行每行两个非负整数fa, ch,第i + 2行描述结点i + 1的父亲编号fa,以及父子关系ch,(ch
= 0 表示i + 1为左儿子,ch = 1表示i
+ 1为右儿子)。

结点1一定是二叉树的根。

【输出格式】

仅一行包含一个整数,表示最少的修改次数。

【样例输入】

3

2 2 2

1 0

1 1

【样例输出】

2

【数据范围】

20 % :n <= 10 , ai <= 100.

40 % :n <= 100 , ai <= 200

60 % :n <= 2000 .

100 % :n <= 10 ^ 5 ,  ai < 2 ^
31.

 

/*
想到了中序遍历然后做lis
但是只25分 有一种情况是
2 5 3 4
这样lis是3 按说改一个5就行
但是题目限制了改成整数 2 3之间不能填了
这就wawawawawa~
这里学习了一种常见的将严格上升的的序列等价转化成不降的序列的方法
 a1 a2 a3 -> a1-1 a2-2 a3-3
这样再做不降的lis就好了
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define maxn 200010
using namespace std;
int n,a[maxn],b[maxn],len,lc[maxn],rc[maxn],c[maxn],r;
void Dfs(int x){
    if(lc[x])Dfs(lc[x]);
    b[++len]=x;
    if(rc[x])Dfs(rc[x]);
}
void LIS(){
    for(int i=1;i<=len;i++){
        int x=a[b[i]];x-=i;
        if(x>=c[r]){
            c[++r]=x;
            continue;
        }
        int p=upper_bound(c+1,c+1+r,x)-c;
        c[p]=x;
    }
}
int main()
{
    freopen("binary.in","r",stdin);
    freopen("binary.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    int x,y;
    for(int i=2;i<=n;i++){
        scanf("%d%d",&x,&y);
        if(y==0)lc[x]=i;
        if(y==1)rc[x]=i;
    }
    Dfs(1);
    LIS();
    printf("%d\n",len-r);
    return 0;
}

 

2.数字对

【题目描述】

小H是个善于思考的学生,现在她又在思考一个有关序列的问题。

她的面前浮现出一个长度为n的序列{ai},她想找出一段区间[L, R](1 <= L <= R <= n)。

这个特殊区间满足,存在一个k(L <= k <= R),并且对于任意的i(L <= i <= R),ai都能被ak整除。这样的一个特殊区间 [L, R]价值为R - L。

小H想知道序列中所有特殊区间的最大价值是多少,而有多少个这样的区间呢?这些区间又分别是哪些呢?你能帮助她吧。

【输入格式】

第一行,一个整数n.

第二行,n个整数,代表ai.

【输出格式】

第一行两个整数,num和val,表示价值最大的特殊区间的个数以及最大价值。

第二行num个整数,按升序输出每个价值最大的特殊区间的L.

【样例输入1】

5

4 6 9 3 6

【样例输出1】

1 3

2

【样例输入2】

5

2 3 5 7 11

【样例输出2】

5 0

1 2 3 4 5

【数据范围】

30%:
1 <= n <= 30 , 1 <= ai <= 32.

60%:
1 <= n <= 3000 , 1 <= ai <= 1024.

80%:
1 <= n <= 300000 , 1 <= ai <= 1048576.

100%: 1 <= n <= 500000 , 1 <= ai < 2 ^ 31.

暴力:

/*
n*n暴力 枚举ak 然后左右拓展
虽然是暴力 但是跑的飞快~~
注意输出的是不一样的区间....
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 500010
using namespace std;
int n,a[maxn],mxx,mxl,sum,Ans[maxn];
struct node{
    int len,L;
}ans[maxn];
int init(){
    int x=0;char s=getchar();
    while(s<‘0‘||s>‘9‘)s=getchar();
    while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
    return x;
}
int cmp(const node &x,const node &y){
    if(x.len==y.len)return x.L<y.L;
    return x.len>y.len;
}
int Gcd(int a,int b){
    return !b?a:Gcd(b,a%b);
}
int main()
{
    freopen("pair.in","r",stdin);
    freopen("pair.out","w",stdout);
    n=init();
    for(int i=1;i<=n;i++)
        a[i]=init();
    for(int k=1;k<=n;k++){
        int li=k,ri=k,gcd=a[k];
        for(int i=k+1;i<=n;i++)
            if(Gcd(gcd,a[i])!=gcd)break;
            else ri++;
        for(int i=k-1;i>=1;i--)
            if(Gcd(gcd,a[i])!=gcd)break;
            else li--;
        ans[k].len=ri-li;ans[k].L=li;
    }
    sort(ans+1,ans+1+n,cmp);
    mxx=ans[1].len;mxl=ans[1].L;
    Ans[++sum]=mxl;
    for(int k=2;k<=n;k++)
        if(ans[k].len!=mxx)break;
        else if(ans[k].L!=mxl){
            Ans[++sum]=ans[k].L;
            mxl=ans[k].L;
        }
    printf("%d %d\n",sum,mxx);
    for(int i=1;i<=sum;i++)
        printf("%d ",Ans[i]);
    return 0;
}

ST表:

/*
nlogn做法
同样的枚举ak 左右拓展的时候二分来搞
这里恰好有单调性~
ST表预处理一下 O(1)查询
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 500010
using namespace std;
int n,a[maxn],f[maxn][20],p[maxn],mxx,mxl,sum,Ans[maxn];
struct node{
    int len,L;
}ans[maxn];
int init(){
    int x=0;char s=getchar();
    while(s<‘0‘||s>‘9‘)s=getchar();
    while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
    return x;
}
int cmp(const node &x,const node &y){
    if(x.len==y.len)return x.L<y.L;
    return x.len>y.len;
}
int Gcd(int a,int b){
    return !b?a:Gcd(b,a%b);
}
int Get_pow(int x){
    for(int i=0;;i++)
        if((1<<i)>x)return i-1;
}
void Get_ST(){
    for(int i=1;i<=n;i++)
        f[i][0]=a[i];
    for(int j=1;j<=18;j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
            f[i][j]=Gcd(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    for(int i=1;i<=n;i++)
        p[i]=Get_pow(i);
}
int find(int l,int r){
    if(l>r)return 0;
    int len=p[r-l+1];
    return Gcd(f[l][len],f[r-(1<<len)+1][len]);
}
int main()
{
    freopen("pair.in","r",stdin);
    freopen("pair.out","w",stdout);
    n=init();
    for(int i=1;i<=n;i++)
        a[i]=init();
    Get_ST();
    for(int k=1;k<=n;k++){
        int li=k,ri=k,gcd=a[k],l,r;
        l=0;r=n-k+1;
        while(l<=r){
            int mid=l+r>>1;
            int x=find(k,k+mid-1);
            if(x==gcd){
                ri=k+mid-1;l=mid+1;
            }
            else r=mid-1;
        }
        l=0;r=k;
        while(l<=r){
            int mid=l+r>>1;
            int x=find(k-mid+1,k);
            if(x==gcd){
                li=k-mid+1;l=mid+1;
            }
            else r=mid-1;
        }
        ans[k].len=ri-li;ans[k].L=li;
    }
    sort(ans+1,ans+1+n,cmp);
    mxx=ans[1].len;mxl=ans[1].L;
    Ans[++sum]=mxl;
    for(int k=2;k<=n;k++)
        if(ans[k].len!=mxx)break;
        else if(ans[k].L!=mxl){
            Ans[++sum]=ans[k].L;
            mxl=ans[k].L;
        }
    printf("%d %d\n",sum,mxx);
    for(int i=1;i<=sum;i++)
        printf("%d ",Ans[i]);
    return 0;
}

3.交换

【题目描述】

给定一个{0, 1, 2, 3, … , n - 1}的排列 p。一个{0, 1, 2 , … , n - 2}的排列q被认为是优美的排列,当且仅当q满足下列条件:

对排列s = {0, 1, 2, 3, ..., n - 1}进行n – 1次交换。

  1. 交换s[q0],s[q0 + 1]
  2. 交换s[q1],s[q1 + 1]

最后能使得排列s = p.

问有多少个优美的排列,答案对10^9+7取模。

【输入格式】

第一行一个正整数n.

第二行n个整数代表排列p.

【输出格式】

仅一行表示答案。

【样例输入】

3

1 2 0

【样例输出】

1

【样例解释】

q = {0,1}
{0,1,2} ->{1,0,2} -> {1, 2, 0}

q = {1,0}
{0,1,2} ->{0,2,1} -> {2, 0, 1}

【数据范围】

30%:  n <= 10

100%:  n <= 50

暴力:

/*直接暴力n!*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 51
using namespace std;
int n,p[maxn],q[maxn],s[maxn],ans;
int main()
{
    freopen("swap.in","r",stdin);
    freopen("swap.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<n;i++)q[i]=i;
    for(int i=1;i<=n;i++){
        int x;scanf("%d",&x);
        p[i]=x+1;
    }
    do{
        for(int i=1;i<=n;i++)s[i]=i;
        for(int i=1;i<n;i++)swap(s[q[i]],s[q[i]+1]);
        int falg=0;
        for(int i=1;i<=n;i++)
            if(s[i]!=p[i]){
                falg=1;break;
            }
        if(falg==0)ans++;
    }while(next_permutation(q+1,q+n));
    printf("%d\n",ans);
}

时间: 2024-10-08 10:33:44

9.2noip模拟试题的相关文章

模拟试题B

模拟试题B 一.单项选择题(2′*8 =16′) 1.灰度等级为256级,分辨率为2048*1024的显示器,至少需要的帧缓存容量为( ) A)512KB B)1MB C)2MB D)3MB 2.在多形边面片的数量非常大的情况下,哪一个消隐算法速度最快? ( ) A)深度缓存算法(Z-Buffer) B)光线跟踪算法 C)画家算法 D)不确定 3.双线性光强插值法(Gouraud Shading)存在哪些问题?( ) A)光照强度在数值上不连续 B)生成多面体真实感图形效果差 C)生成曲面体真实

模拟试题C

模拟试题C 一.单项选择题(2′*14 =28′) 1.双线性法向插值法(Phong Shading)的优点是( ) A)法向计算精确 B)高光域准确 C)对光源和视点没有限制 D)速度较快 2.用编码裁剪法裁剪二维线段时,判断下列直线段采用哪种处理方法.假设直线段两个端点M.N的编码为1000和1001(按TBRL顺序)( ) A)直接舍弃 B)直接保留 C)对MN再分割求交 D)不能判断 3.下面哪个不是齐次坐标的特点( ) A)用n+1维向量表示一个n维向量 B)将图形的变换统一为图形的坐

计算机职称考试题库Internet模块操作练习模拟试题(一)

1.请为当前计算机添加连接到com1口的标准56000 bps调制解调器设备,要求不检测当前连接设备. 当前界面:开始à控制面板 方法一: 打开[电话和调整解调器选项]à[调整解调器]选项卡à[添加]按钮à选中[不要检测我的调制解调器设备……]à下一步à型号:标准 56000 bps 调制解调器à下一步à选定的端口:com1à下一步à完成 方法二: 添加新硬件à下一步à选择[是,我已经连接了此硬件]à下一步à列表拉到最后选择[添加新的硬件设备]à下一步à选择[安装我手动从列表选择的硬件(高级)]

2014年软考-信息技术处理员-模拟试题及答案【第一章】

51CTO学院,在软考备考季特别整理了"2014年软考信息技术处理员模拟试题及答案[汇总篇]",帮助各位学院顺利过关!更多软件水平考试辅导及试题,请关注51CTO学院-软考分类吧! 查看汇总:2014年软考-信息技术处理员-模拟试题及答案[汇总篇]  ●在计算机内部用来传送.存储.加工处理的数据或指令都是以____(1)_B___形式进行的. A. 十进制码 B.二进制码 C.八进制码 D.十六进制码 ●如果一个存储单元能存放一个字节,那么一个32KB的存储器共有____(2)_B__

2014年软考-信息技术处理员-模拟试题及答案【第二章】

51CTO学院,在软考备考季特别整理了"2014年软考信息技术处理员模拟试题及答案[汇总篇]",帮助各位学院顺利过关!更多软件水平考试辅导及试题,请关注51CTO学院-软考分类吧! 查看汇总:2014年软考-信息技术处理员-模拟试题及答案[汇总篇]  ●计算机网络的主要目标是实现____(16 )__C__. A.数据处理 B.文献检索 C.资源共享和信息传输 D.信息传输 ●Internet上,访问Web网站时用的工具是浏览器.下列____(17 )_A___就是目前常用的Web浏览

2014年软考-信息技术处理员-模拟试题及答案【第三章】

51CTO学院,在软考备考季特别整理了"2014年软考信息技术处理员模拟试题及答案[汇总篇]",帮助各位学院顺利过关!更多软件水平考试辅导及试题,请关注51CTO学院-软考分类吧! 查看汇总:2014年软考-信息技术处理员-模拟试题及答案[汇总篇]  ●备注视图中的注释信息在文稿演示时____(31)__B__. A.会显示 B.不会显示 C.显示一部分 D.显示标题 ●Access 2000关系数据库是____(32)_D___的集合. A.数据 B.数据库对象 C.表 D.关系 ●

2014年软考-信息技术处理员-模拟试题及答案【第四章】

51CTO学院,在软考备考季特别整理了"2014年软考信息技术处理员模拟试题及答案[汇总篇]",帮助各位学院顺利过关!更多软件水平考试辅导及试题,请关注51CTO学院-软考分类吧! 查看汇总:2014年软考-信息技术处理员-模拟试题及答案[汇总篇]  ●Office家族为用户提供了各种不同类型的模板.扩展名为.mdz的模板是____(41)D____中的模板. A.Word B.Excel C.PowerPoint D.Access ●在Excel中,选取一行单元格的方法是____(4

2014年软考-信息技术处理员-模拟试题及答案【第五章】

51CTO学院,在软考备考季特别整理了"2014年软考信息技术处理员模拟试题及答案[汇总篇]",帮助各位学院顺利过关!更多软件水平考试辅导及试题,请关注51CTO学院-软考分类吧! 查看汇总:2014年软考-信息技术处理员-模拟试题及答案[汇总篇]  ●管理信息系统科学的3要素是系统的观点.数学的方法和____(51)A____. A.计算机的应用 B.计算机科学 C.计算机理论 D.计算机方法 ●知识产权可分为:____(52)___C_两类. A.农业产权和著作权 C.工业产权和著

2014年软考-信息技术处理员-模拟试题及答案【第六章】

51CTO学院,在软考备考季特别整理了"2014年软考信息技术处理员模拟试题及答案[汇总篇]",帮助各位学院顺利过关!更多软件水平考试辅导及试题,请关注51CTO学院-软考分类吧! 查看汇总:2014年软考-信息技术处理员-模拟试题及答案[汇总篇]  ●Access数据库的类型是____(61)_C___. A.层次数据库 B.网状数据库 C.关系数据库 D.面向对象数据库 ●在Word文档操作中,经常利用____(62)_C___操作过程相互配合,用以将一段文本内容移到另一处. A.