9.30 noip模拟试题

时限均为1s,内存 256MB

1、某种密码(password.*)

关于某种密码有如下描述:某种密码的原文A是由N个数字组成,而密文B是一个长度为N的01数串,原文和密文的关联在于一个钥匙码KEY。若KEY=∑?〖Ai*Bi〗,则密文就是原文的一组合法密码。

现在有原文和钥匙码,请编一个程序来帮助他统计到底有多少个符合条件的密文。

【输入数据】

第一行两个数N,KEY,意义同题目描述;

第二行N个数表示原文A,意义同题目描述。

【输出数据】

一个数ANS,表示对于原文A和KEY,有多少组可行的密文B。

【输入样例】

3 2

1 1 2

【输出样例】

2

【样例说明】

密文110,1*1+1*1+0*2=2

密文001,0*1+0*1+1*2=2

一共两组可行的密文。

【数据约定】

60%数据满足N<=25

100%数据满足N<=40,-maxlongint<=∑?Ai<=maxlongint

暴力+hash

/*蒟蒻用map*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#define ll long long
using namespace std;
long long n,k,N,a[50],falg,ans;
map<long long,long long>p;
void Dfs(long long now,long long s){
    if(now==N+1){
        if(!falg)p[s]++;
        else ans+=p[k-s];
        return;
    }
    Dfs(now+1,s);
    Dfs(now+1,s+a[now]);
}
int main()
{
    freopen("password.in","r",stdin);
    freopen("password.out","w",stdout);
    cin>>n>>k;
    for(long long i=1;i<=n;i++)cin>>a[i];
    N=n/2;Dfs(1,0);
    falg=1;N=n;Dfs(n/2+1,0);
    cout<<ans;
    return 0;
}

2、球的序列(formation.*)

N个编号为1-n的球,每个球都有唯一的编号。这些球被排成两种序列,分别为A、B序列,现在需要重新寻找一个球的序列l,对于这个子序列l中任意的两个球,要求j,k(j<k),都要求满足lj在A中位置比lk在A中位置靠前,却lj在B中位置比lk在B中位置靠前,请你计算这个子序列l的最大长度。

输入:

第一行一个整数,表示N。

第二行N个整数,表示A序列。

第三行N个整数,表示B序列。

样例输入

5

1 2 4 3 5

5 2 3 4 1

//5 2 4 3 1

样例输出

2

样例说明

L可以是{2,3},也可以是{2,4}

数据范围:

40% N<=5000

100% N<=50000

暴力LCS 40

#include<cstdio>
#define maxn 10010
using namespace std;
int n,a[maxn],b[maxn];
short f[maxn][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;
}
short max(short x,short y){
    return x>y?x:y;
}
int main()
{
    freopen("formation.in","r",stdin);
    freopen("formation.out","w",stdout);
    n=init();
    for(int i=1;i<=n;i++)a[i]=init();
    for(int i=1;i<=n;i++)b[i]=init();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(a[i]==b[j])f[i][j]=f[i-1][j-1]+1;
            else f[i][j]=max(f[i-1][j],f[i][j-1]);
    printf("%d\n",f[n][n]);
    return 0;
}

转化成LIS

/*并不难的题没好好想想~~*/
#include<cstdio>
#include<algorithm>
#define maxn 50010
using namespace std;
int n,a[maxn],b[maxn],c[maxn],r;
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 max(int x,int y){
    return x>y?x:y;
}
void LIS(){
    for(int i=1;i<=n;i++){
        int x=b[i];
        if(x>c[r]){
            c[++r]=x;
            continue;
        }
        int p=lower_bound(c+1,c+1+r,x)-c;
        c[p]=x;
    }
}
int main()
{
    //freopen("formation.in","r",stdin);
    //freopen("formation.out","w",stdout);
    n=init();int x;
    for(int i=1;i<=n;i++){
        x=init();a[x]=i;
    }
    for(int i=1;i<=n;i++){
        x=init();b[i]=a[x];
    }
    LIS();
    printf("%d\n",r);
    return 0;
}

3大逃亡(escape.*)

给出数字N(1<=N<=10000),X(1<=x<=1000),Y(1<=Y<=1000),代表有N个敌人分布一个X行Y列的矩阵上,矩形的行号从0到X-1,列号从0到Y-1再给出四个数字x1,y1,x2,y2,代表你要从点(x1,y1)移到(x2,y2)。在移动的过程中你当然希望离敌人的距离的最小值最大化,现在请求出这个值最大可以为多少,以及在这个前提下,你最少要走多少步才可以回到目标点。注意这里距离的定义为两点的曼哈顿距离,即某两个点的坐标分为(a,b),(c,d),那么它们的距离为|a-c|+|b-d|。

输入:

第一行给出数字N,X,Y

第二行给出x1,y1,x2,y2

下面将有N行,给出N个敌人所在的坐标

输出:

在一行内输出你离敌人的距离及在这个距离的限制下,你回到目标点最少要移动多少步。

Sample input

2 5 6

0 0 4 0

2 1

2 3

Sample output

2 14

 

/*本来能A的 但写wa了 这种题又没法拍 哎QAQ*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 1010
using namespace std;
int n,m,k,f[maxn][maxn],dis[maxn][maxn];
int x1,x2,y1,y2,ans,step;
struct node{
    int x,y,s;
};
int xx[4]={0,0,1,-1};
int yy[4]={1,-1,0,0};
queue<node>q;
void Bfs(){
    while(!q.empty()){
        node t=q.front();q.pop();
        dis[t.x][t.y]=t.s;
        for(int i=0;i<4;i++){
            int nx=t.x+xx[i];
            int ny=t.y+yy[i];
            if(nx>0&&nx<=n&&ny>0&&ny<=m&&f[nx][ny]==0){
                f[nx][ny]=1;dis[nx][ny]=t.s+1;
                q.push((node){nx,ny,t.s+1});
            }
        }
    }
}
int Judge(int S){
    if(dis[x1][y1]<S)return -1;//这里没考虑到
    memset(f,0,sizeof(f));
    f[x1][y1]=1;
    while(!q.empty())q.pop();
    q.push((node){x1,y1,0});
    while(!q.empty()){
        node t=q.front();q.pop();
        if(t.x==x2&&t.y==y2)
            return t.s;//开始wa的时候是返回01 并且直接改
        for(int i=0;i<4;i++){
            int nx=t.x+xx[i];
            int ny=t.y+yy[i];
            if(nx>0&&nx<=n&&ny>0&&ny<=m&&f[nx][ny]==0&&dis[nx][ny]>=S){
                f[nx][ny]=1;
                q.push((node){nx,ny,t.s+1});
            }
        }
    }
    return -1;
}
int main()
{
    freopen("escape.in","r",stdin);
    freopen("escape.out","w",stdout);
    scanf("%d%d%d",&k,&n,&m);
    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    x1++;x2++;y1++;y2++;
    int x,y;
    memset(dis,127/3,sizeof(dis));
    for(int i=1;i<=k;i++){
        scanf("%d%d",&x,&y);
        x++;y++;
        q.push((node){x,y,0});
        f[x][y]=1;dis[x][y]=0;
    }
    Bfs();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            printf("%d ",dis[i][j]);
        printf("\n");
    }
    int l=0,r=maxn*maxn;
    while(l<=r){
        int mid=(l+r)/2;
        int tmp=Judge(mid);
        if(tmp!=-1){
            l=mid+1;ans=mid;
            step=tmp;
        }
        else r=mid-1;
    }
    printf("%d %d\n",ans,step);
    return 0;
}

时间: 2024-10-06 05:10:35

9.30 noip模拟试题的相关文章

10.7 noip模拟试题

楼[问题背景]zhx 为他的妹子造了一幢摩天楼.[问题描述]zhx 有一幢摩天楼. 摩天楼上面有 M 个观光电梯,每个观光电梯被两个整数???? " ,???? " 描述.每个电梯只有两个按钮, (针对第 i 个电梯)两个按钮分别可以使电梯向上???? " 层向下???? " 层.摩天楼的高度是无限的,但是电梯不可以钻入地下,也就是说是有下限的.每层楼用整数标记, 以 0 作为地面这一层的标记.zhx 去陪他妹子了,留你一个人在摩天楼的 0 层,现在你想知道,仅可以

2016.10.30 NOIP模拟赛 day2 PM 整理

满分:300分 直接全部爆零,真的是很坑啊! 10.30的题目+数据:链接:http://pan.baidu.com/s/1jHXLace 密码:i784 T1: 题目中的难点就是每次折叠的点可能应经被覆盖了,我的做法是递归去推出它现在在哪个位置,不仅超时,而且答案错误. 也曾想过用数组去存下它当前的位置,但是被10^18的数据吓到了. 正解:并不是所有的坐标都有用,仅仅是那m个将要用到的点有用,所以每次折叠,就只对之后的有用的k个点进行更新,这样就行了. 时间复杂度O(m^2) 不会超时的.

10.3 noip模拟试题

希望[题目描述]网页浏览器者有后退与前进按钮,一种实现这两个功能的方式是用两个栈,“前进栈”.“后退栈”.这里你需要实现以下几个功能:BACK: 如果“后退栈”为空则忽略此命令. 否则将当前两面压入“前进栈”,从“后退栈”中取出栈顶页面,并设置为当前页面.FORWARD: 如果“前进栈”为空则忽略此命令.否则将当前两面压入“后退栈”,从“前进栈”中取出栈顶页面,并设置为当前页面.VISIT: 将当前页面压入“后退栈”. 并将当前页面置为指定页面, 并将“前进栈”置空.QUIT: 退出.假设此浏览

10.27 noip模拟试题(moring)

WPS转word太丑了 凑合看喽 第二题 [题目描述] 给你两个日期,问这两个日期差了多少毫秒. [输入格式] 两行,每行一个日期,日期格式保证为“YYYY-MM-DD hh:mm:ss ”这种形式.第二个日期时间一定比第一个日期时间要大两个日期的年份一定都是 21 世纪的年份. [输出格式] 一行一个整数代表毫秒数. [样例输入 1] 2000-01-01 00:00:00 2000-01-01 00:00:01 [样例输出 1] 1000 [样例输入 2] 0 1 2 3 4 5 6 7 8

9.26 noip模拟试题

魔术球问题弱化版(ball.c/.cpp/.pas) 题目描述 假设有 n 根柱子,现要按下述规则在这 n 根柱子中依次放入编号为 1,2,3,…的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何 2 个相邻球的编号之和为完全平方数. 试设计一个算法,计算出在 n 根柱子上最多能放多少个球.例如,在 4 根柱子上最多可放 11 个球. 对于给定的 n,计算在 n 根柱子上最多能放多少个球. 输入描述 第 1 行有 1 个正整数 n,表示柱子数. 输出描述 一行表示可以放的

神奇的Noip模拟试题第一试 合理种植 枚举+技巧

1.合理种植 (plant.pas/.c/.cpp) [问题描述] 大COS在氯铯石料场干了半年,受尽了劳苦,终于决定辞职.他来到表弟小cos的寒树中学,找到方克顺校长,希望寻个活干. 于是他如愿以偿接到了一个任务…… 美丽寒树中学种有许多寒树.方克顺希望校园无论从什么角度看都是满眼寒树,因此他不希望有三棵甚至更多寒树种在一条直线上.现在他把校园里n棵寒树的坐标都给了大COS,让他数出存在多少多树共线情况.(若一条直线上有三棵或以上的树,则算出现一个多树共线情况.) [输入] 输入文件名为pla

11.13 noip模拟试题

题目名称 笔记 括号 城堡可执行文件名 note brackets castle输入文件名 note.in brackets.in castle.in输出文件名 note.in brackets.out castle.in每个测试点时限 1 秒 1 秒 1 秒内存限制 512MB 512MB 512MB测试点数目 20 20 10每个测试点分值 5 5 10是否有部分分 否 否 否题目类型 传统型 传统型 传统型测试题 #4 笔记笔记[问题描述]给定一个长度为?的序列?,下标编号为1~?.序列的

2016.10.30 NOIP模拟赛 day2 AM 整理

题目+数据:链接:http://pan.baidu.com/s/1gfBg4h1 密码:ho7o 总共得了:130分, 1:100分  2:30分(只会这30分的暴力) 3:0(毫无思路) 虽然不高,但是比较满意,因为把自己会的分数都拿到了. T1:100分 1 /* 2 T1明显是个数论题. 3 正确的思路:把n!质因数分解,把所有质因数的指数都取到最大的偶数,它们的乘积便是最终的结果. 4 有一种很快的方法在Eular筛中可以n!的质因数分解. 5 if(!is_prim[i]) 6 { 7

9.20 noip模拟试题

  Problem 1 双色球(ball.cpp/c/pas) [题目描述] 机房来了新一届的学弟学妹,邪恶的chenzeyu97发现一位学弟与他同名,于是他当起了善良的学长233 “来来来,学弟,我考你道水题检验一下你的水平……” 一个栈内初始有n个红色和蓝色的小球,请你按照以下规则进行操作 只要栈顶的小球是红色的,将其取出,直到栈顶的球是蓝色 然后将栈顶的蓝球变成红色 最后放入若干个蓝球直到栈中的球数为n 以上3步骤为一次操作 如栈中都是红色球,则操作停止,请问几次操作后停止 chenzey