11.12 noip模拟试题

题目名称 加密 冒泡排序图 重建
可执行文件名 encrypt bubble rebuild
输入文件名 encrypt.in bubble.in rebuild.in
输出文件名 encrypt.in bubble.out rebuild.in
每个测试点时限 1 秒 1 秒 1 秒
内存限制 512MB 512MB 512MB
测试点数目 10 20 10
每个测试点分值 10 5 10
是否有部分分 否 否 否
题目类型 传统型 传统型 传统型
测试题 #3 加密

加密
【问题描述】
有一种不讲道理的加密方法是: 在字符串的任意位置随机插入字符。 相应的,
不讲道理的解密方法就是从字符串中恰好删去随机插入的那些字符。
给定原文?和加密后的字符串?,求?有多少子串可以通过解密得到原文?。
【输入格式】
输入第一行包含一个字符串?,第二行包含一个字符串?。
【输出格式】
输出一行,包含一个整数,代表可以通过解密得到原文的?的子串的数量。
【样例输入】
abcabcabc
cba
【样例输出】
9
【样例解释】
用[?,?]表示子串开头结尾的下标(从 0 开始编号) ,这 9 种方案是:
[0,6],[0,7],[0,8],[1,6],[1,7],[1,8],[2,6],[2,7],[2,8]
【数据规模和约定】
30%的数据,|?| 1000。
对于100%的数据,1 ≤ |?| ≤ 300,000,1 ≤ ? ≤ 200。

/*
这题没想出来不应该啊 .....
考试的时候考虑这样做 找每个最小的覆盖区间
但是有重复 似乎就搞到了容斥原理上
其实每找到一个区间 然后回头找 找到最近的合法的
假设 大区间是 [s,t] 回头找的是 [ss,t] 那么
我们累计贡献 (s-last)*(n-s+1) 下一次从ss开始找
last是上次一的ss在哪 这样就很好的解决了这个区间重复的问题
因为每次的起点限制在ss之后 而之前统计的区间起点都一定在ss之前
这样就好了
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#define maxn 300010
using namespace std;
int n,m;
long long ans;
char a[maxn],b[maxn];
int main()
{
    freopen("encrypt.in","r",stdin);
    freopen("encrypt.out","w",stdout);
    scanf("%s%s",a+1,b+1);
    n=strlen(a+1);m=strlen(b+1);
    int s=0,t=0,st=0;while(s<=n){
        if(a[++s]==b[t+1])t++;
        if(t==m){
            for(int i=s;i>=1;i--){
                if(a[i]==b[t])t--;
                if(t==0){t=i;break;}
            }
            ans+=(t-st)*(n-s+1);s=st=t;t=0;
        }
    }
    cout<<ans<<endl;
    fclose(stdin);fclose(stdout);
    return 0;
}

测试题 #3 冒泡排序图
冒泡排序图
【问题描述】
有一段使用冒泡排序产生一张图的伪代码如下:
function bubbleSortGraph(n, a[]):
graph = emptyGraph()
repeat
swapped = false
for i = 1 to n - 1:
if a[i] > a[i + 1]:
graph.addEdge(a[i], a[i + 1])
swap(a[i], a[i + 1])
swapped = true
until not swapped
return graph
函数的输入为长度为?的排列?[],输出为一张?个节点的无向图。函数中,
emptyGraph()创造了一张空的无向图,addEdge(x, y)向图中添加了一条 x
和 y 之间的无向边,最后返回的 graph 即产生的无向图。
图的点独立集为图中节点集合的一个子集。如果集合?是图?的点独立集,
那么?中任意两个节点在图?中都没有边直接相连。
给定1~?的一个排列, 请求出按照伪代码生成的无向图的最大点独立集的大
小,以及一定会存在于最大点独立集中的节点。
【输入格式】
输入第一行包含一个整数?。接下来一行包含?个空格分隔的整数,代表序
列?[]。
【输出格式】
输出两行。 第一行包含一个整数, 代表生成的无向图的最大点独立集的大小。
第二行输出最大点独立集中一定会包含的节点在输入序列中对应的下标, 按照从
小到大的顺序输出,以空格分隔。
【样例输入】
3
3 1 2
【样例输出】
2
2 3
测试题 #3 冒泡排序

【数据规模和约定】
36。
60%的数据,? ≤ 1000。
对于100%的数据,1 ≤ ? ≤ 100,000。
【提示】
一定存在于最大点独立集中的节点数未必等于最大点独立集的大小。
测试题 #3 重建

傻逼暴力55

#include<iostream>
#include<cstdio>
#define maxn 100010
using namespace std;
int n,a[maxn],f[maxn],g[maxn],ans;
int init(){
    int x=0,f=1;char s=getchar();
    while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
    while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
    return x*f;
}
void Dfs(int x,int y){
    for(int i=x-1;i>=1;i--)
        if(a[i]<a[x]&&f[i]+1==y){
            g[i]=1;Dfs(i,f[i]);
        }
}
int main()
{
    freopen("bubble.in","r",stdin);
    freopen("bubble.out","w",stdout);
    n=init();
    for(int i=1;i<=n;i++)
        a[i]=init(),f[i]=1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<i;j++)
            if(a[i]>a[j])f[i]=max(f[i],f[j]+1);
    for(int i=1;i<=n;i++)
        ans=max(ans,f[i]);
    for(int i=n;i>=1;i--)
        if(f[i]==ans){
            g[i]=1;Dfs(i,ans);
        }
    printf("%d\n",ans);
    for(int i=1;i<=n;i++){
        int falg=0;if(!g[i])continue;
        for(int j=i+1;j<=n;j++)
            if(f[i]==f[j]&&g[j]){
                g[j]=0;falg=1;
        }
        if(!falg)printf("%d ",i);
    }
    fclose(stdin);fclose(stdout);
    return 0;
}

改改

/*
自己改的跑了5s多 基本一个点就是同桌的total
这特么就很尴尬了
然后打开了std
.....
果然是把dfs找路径的过程改了 正着最长上升 到这最长
然而没有自己想的那么麻烦 a[i]=-a[i](就像懒得重载优先队列一样的*-1)
想到这句就好多了 多了 剩下的一毛一样
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 100010
using namespace std;
int n,a[maxn],c[maxn],num,f[maxn],g[maxn],r[maxn];
int init(){
    int x=0,f=1;char s=getchar();
    while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
    while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
    return x*f;
}
int main()
{
    //freopen("bubble.in","r",stdin);
    //freopen("bubble.out","w",stdout);
    n=init();
    for(int i=1;i<=n;i++)a[i]=init();
    for(int i=1;i<=n;i++){
        int x=a[i];if(x>c[num]){
            c[++num]=x;f[i]=num;continue;
        }
        int pos=lower_bound(c+1,c+1+num,x)-c;
        c[pos]=x;f[i]=pos;
    }
    printf("%d\n",num);num=0;c[0]=-maxn;
    for(int i=n;i>=1;i--){
        int x=-a[i];if(x>c[num]){
            c[++num]=x;g[i]=num;continue;
        }
        int pos=lower_bound(c+1,c+1+num,x)-c;
        c[pos]=x;g[i]=pos;
    }
    for(int i=1;i<=n;i++)
        if(f[i]+g[i]==num+1)r[f[i]]++;
    for(int i=1;i<=n;i++){
        if(f[i]+g[i]==num+1&&r[f[i]]==1)
            printf("%d ",i);
    }
    fclose(stdin);fclose(stdout);
    return 0;
}

重建
【问题描述】
给定一个?个点?条边的有向图。你可以选择一个节点?,然后重建所有能
从?到达,而且能到达?的所有节点(包括?自身) 。此外,你还可以先将一条边
改成双向边,然后再进行上面的选择。
请你求出最多可以重建的节点数, 并求出通过选择哪些边改成双向边才能使
重建的节点达到最多。
【输入格式】
输入的第一行包含两个整数?和?。
接下来?行,每行包含两个整数?和?,描述一条有向边。
保证图中任意两点在任意方向上最多只有一条边直接相连。
【输出格式】
输出三行。第一行输出一个整数,最多可以重建的节点数。
第二一个整数?,代表有?条边能使重建节点数达到最多。
第三行输出?个整数,代表可以选择的边的编号。边按照输入顺序从 1 开始
编号。请按照从小到大的顺序输出,并以空格分隔。
【样例输入 1】
5 4
1 2
2 3
1 3
4 1
【样例输出 1】
3
1
3
【样例输入 2】
3 4
1 2
2 1
1 3
3 1
测试题 #3 重建
第 6 页 共 6 页
【样例输出 2】
3
4
1 2 3 4
【数据规模和约定】
3?,? ≤ 10。
60%的数据,? ≤ 1500,? ≤ 100,000。
对于100%的数据,1 ≤ ? ≤ 2000,? ≤ ? × ?。

30

/*
自己写的缩点然后求两点之间的最长路
wa了几个点 好奇的打开了数据
然而看不出啥 造了一坨小数据和暴力排
终于 发现了错误
不是求两点之间的最长路 有可能有两条路 或者更多
就比如 1->2->3
       1->4->3
       1->3
如果跑1->3的最长路 就弄丢了另一条
这特么就很尴尬了
数据还给了30分23333
经过一个小时的对拍+画图 终于找到了错误
然而不会改了.....不会改了
打开了std 很机智的bitset 然而不会用 于是乎弃疗了
答题的思路就是 维护每个点能到那些点 这里用位运算优化
然后剩下的思路就差不多了
*/
#include<cstdio>
#include<queue>
#include<iostream>
#define inf 1e8
#define maxn 2010
using namespace std;
int n,m,num,head[maxn],mx[maxn][maxn],bl[maxn],cnt,ans[maxn*maxn],vis[maxn][maxn];
int N,M,Head[maxn],v[maxn],dfn[maxn],low[maxn],f[maxn],s[maxn],top,topt;
queue<int>q;
struct node{
    int v,pre;
}e[maxn*maxn],p[maxn*maxn];
struct edge{
    int u,v;
}E[maxn*maxn];
int init(){
    int x=0,f=1;char s=getchar();
    while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
    while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
    return x*f;
}
void Add(int from,int to){
    num++;e[num].v=to;
    e[num].pre=head[from];
    head[from]=num;
}
void Ad(int from,int to){
    printf("%d %d\n",from,to);
    if(vis[from][to])return;
    vis[from][to]=1;
    M++;p[M].v=to;
    p[M].pre=Head[from];
    Head[from]=M;
}
void Tarjan(int x){
    dfn[x]=low[x]=++topt;
    f[x]=1;s[++top]=x;
    for(int i=head[x];i;i=e[i].pre){
        int v=e[i].v;
        if(dfn[v]==0){
            Tarjan(v);low[x]=min(low[x],low[v]);
        }
        else if(f[v])low[x]=min(low[x],dfn[v]);
    }
    if(low[x]==dfn[x]){
        N++;while(x!=s[top]){
            v[N]++;bl[s[top]]=N;f[s[top]]=0;--top;
        }
        v[N]++;bl[s[top]]=N;f[s[top]]=0;--top;
    }
}
/*void Dfs(int s,int now,int from){
    mx[s][now]=max(mx[s][now],mx[s][from]+v[now]);
    for(int i=Head[now];i;i=p[i].pre){
        int v=p[i].v;Dfs(s,v,now);
    }
}*/
void SPFA(int s){
    for(int i=1;i<=n;i++)f[i]=0;
    f[s]=1;mx[s][s]=v[s];q.push(s);
    while(!q.empty()){
        int k=q.front();f[k]=0;q.pop();
        for(int i=Head[k];i;i=p[i].pre){
            int to=p[i].v;
            if(mx[s][to]<mx[s][k]+v[to]){
                mx[s][to]=mx[s][k]+v[to];
                if(f[to]==0){
                    f[to]=1;q.push(to);
                }
            }
        }
    }
}
int main()
{
    freopen("rebuild.in","r",stdin);
    freopen("rebuild.out","w",stdout);
    n=init();m=init();int u,v;
    for(int i=1;i<=m;i++){
        u=init();v=init();Add(u,v);
        E[i].u=u;E[i].v=v;
    }
    for(int i=1;i<=n;i++)
        if(dfn[i]==0)Tarjan(i);
        printf("\n");
    for(int u=1;u<=n;u++)
        for(int i=head[u];i;i=e[i].pre){
            int v=e[i].v;if(bl[u]==bl[v])continue;
            Ad(bl[u],bl[v]);
        }printf("\n");
    for(int i=1;i<=N;i++)SPFA(i);
        //Dfs(i,i,0);
    int mxx=0;
    for(int i=1;i<=m;i++){
        u=bl[E[i].u];v=bl[E[i].v];
        if(mx[u][v]>mxx){
            mxx=mx[u][v];
            cnt=0;ans[++cnt]=i;
        }
        else if(mx[u][v]==mxx)
            ans[++cnt]=i;
    }
    printf("%d\n%d\n",mxx,cnt);
    for(int i=1;i<=cnt;i++)
        printf("%d ",ans[i]);
    return 0;
}

时间: 2024-10-10 15:06:50

11.12 noip模拟试题的相关文章

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~?.序列的

2017 11.6 NOIP模拟赛

1.数学老师的报复(attack.pas/c/cpp)[问题描述]11 班数学大佬 YXN 又在上数学课的时候把班主任 MP6 的错误当众挑出来了,MP6 再一次感到很难堪,于是决定报复 YXNMP6 对 YXN 说:给你一个函数 f(x),定义如下:f ( 1 ) = 1f ( 2 ) = 1f ( n ) = ( A * f ( n - 1 ) + B * f ( n - 2 ) ) mod 7.YXN 说这还不简单,可以秒杀!MP6 微微笑了笑说:n 等于 100 你算得出来,那 n 等于

神奇的Noip模拟试题一试 2 排队

2 排队 (lineup.pas/.c/.cpp) [问题描述] 小sin所在的班有n名同学,正准备排成一列纵队,但他们不想按身高从矮到高排,那样太单调,太没个性.他们希望恰好有k对同学是高的在前,矮的在后,其余都是矮的在前,高的在后.如当n=5,k=3时,假设5人从矮到高分别标为1.2.3.4.5,则(1,5,2,3,4).(2,3,1,5,4).(3,1,4,2,5)都是可行的排法.小sin想知道总共有多少种可行排法. [输入] 输入文件名为lineup.in. 一行两个整数n和k,意义见问

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

【数论+技巧】神奇的Noip模拟试题第二试 T1 素数统计

1.      素数统计 (pcount.pas/.c/.cpp) [问题描述] 小tan的老师揣谙戈给同学们布置了一道题,要求统计给定区间内素数的个数.“这不是很简单吗?”小tan忍不住说.揣谙戈冷笑一下说:“等你们看到题目就知道了.”便转身离去. 果然,小tan被那极大的区间吓怕了,现在是你拯救她的时候. [输入] 输入文件名为pcount.in. 输入一行两个正整数a和b,表示给定区间为[a,b]. [输出] 输出文件名为pcount.out. 输出一个整数,表示区间内素数数量. [输入输

10.7 noip模拟试题

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

9.27 noip模拟试题

工资 (money/money.in/money.out) 时限1000ms 内存256MB 聪哥在暑假参加了打零工的活动,这个活动分为n个工作日,每个工作日的工资为Vi.有m个结算工钱的时间,聪哥可以自由安排这些时间,也就是说什么时候拿钱,老板说的不算,聪哥才有发言权!(因为聪哥是土豪,他是老板的老板) 聪哥不喜欢身上一次性有太多的钱,于是他想安排一下拿钱的时间,使他一次性拿的钱中最大的最小.(最后一天一定要领钱) 输入 第一行 2个数 n,m 接下来n行,每行一个数,代表Vi. 输出 最小的

10.4 noip模拟试题

题目名称 PA 青春 三部曲 名称 huakai taritari truetears 输入 huakai.in taritari.in truetears.in 输出 huakai.out taritari.out truetears.out 每个测试点时限 1秒 1秒 1秒 内存限制 512MB 512MB 512MB 测试点数目 10 10 10 每个测试点分值 10 10 10 是否有部分分 无 无 无 题目类型 传统 传统 传统 注意事项(请务必仔细阅读): PA [题目描述] 汉诺塔