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+,b+);
n=strlen(a+);m=strlen(b+);
int s=,t=,st=;while(s<=n){
if(a[++s]==b[t+])t++;
if(t==m){
for(int i=s;i>=;i--){
if(a[i]==b[t])t--;
if(t==){t=i;break;}
}
ans+=(t-st)*(n-s+);s=st=t;t=;
}
}
cout<<ans<<endl;
fclose(stdin);fclose(stdout);
return ;
}
测试题 #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=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
void Dfs(int x,int y){
for(int i=x-;i>=;i--)
if(a[i]<a[x]&&f[i]+==y){
g[i]=;Dfs(i,f[i]);
}
}
int main()
{
freopen("bubble.in","r",stdin);
freopen("bubble.out","w",stdout);
n=init();
for(int i=;i<=n;i++)
a[i]=init(),f[i]=;
for(int i=;i<=n;i++)
for(int j=;j<i;j++)
if(a[i]>a[j])f[i]=max(f[i],f[j]+);
for(int i=;i<=n;i++)
ans=max(ans,f[i]);
for(int i=n;i>=;i--)
if(f[i]==ans){
g[i]=;Dfs(i,ans);
}
printf("%d\n",ans);
for(int i=;i<=n;i++){
int falg=;if(!g[i])continue;
for(int j=i+;j<=n;j++)
if(f[i]==f[j]&&g[j]){
g[j]=;falg=;
}
if(!falg)printf("%d ",i);
}
fclose(stdin);fclose(stdout);
return ;
}
/*
自己改的跑了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=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
int main()
{
//freopen("bubble.in","r",stdin);
//freopen("bubble.out","w",stdout);
n=init();
for(int i=;i<=n;i++)a[i]=init();
for(int i=;i<=n;i++){
int x=a[i];if(x>c[num]){
c[++num]=x;f[i]=num;continue;
}
int pos=lower_bound(c+,c++num,x)-c;
c[pos]=x;f[i]=pos;
}
printf("%d\n",num);num=;c[]=-maxn;
for(int i=n;i>=;i--){
int x=-a[i];if(x>c[num]){
c[++num]=x;g[i]=num;continue;
}
int pos=lower_bound(c+,c++num,x)-c;
c[pos]=x;g[i]=pos;
}
for(int i=;i<=n;i++)
if(f[i]+g[i]==num+)r[f[i]]++;
for(int i=;i<=n;i++){
if(f[i]+g[i]==num+&&r[f[i]]==)
printf("%d ",i);
}
fclose(stdin);fclose(stdout);
return ;
}
重建
【问题描述】
给定一个?个点?条边的有向图。你可以选择一个节点?,然后重建所有能
从?到达,而且能到达?的所有节点(包括?自身) 。此外,你还可以先将一条边
改成双向边,然后再进行上面的选择。
请你求出最多可以重建的节点数, 并求出通过选择哪些边改成双向边才能使
重建的节点达到最多。
【输入格式】
输入的第一行包含两个整数?和?。
接下来?行,每行包含两个整数?和?,描述一条有向边。
保证图中任意两点在任意方向上最多只有一条边直接相连。
【输出格式】
输出三行。第一行输出一个整数,最多可以重建的节点数。
第二一个整数?,代表有?条边能使重建节点数达到最多。
第三行输出?个整数,代表可以选择的边的编号。边按照输入顺序从 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=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';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]=;
M++;p[M].v=to;
p[M].pre=Head[from];
Head[from]=M;
}
void Tarjan(int x){
dfn[x]=low[x]=++topt;
f[x]=;s[++top]=x;
for(int i=head[x];i;i=e[i].pre){
int v=e[i].v;
if(dfn[v]==){
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]]=;--top;
}
v[N]++;bl[s[top]]=N;f[s[top]]=;--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=;i<=n;i++)f[i]=;
f[s]=;mx[s][s]=v[s];q.push(s);
while(!q.empty()){
int k=q.front();f[k]=;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]==){
f[to]=;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=;i<=m;i++){
u=init();v=init();Add(u,v);
E[i].u=u;E[i].v=v;
}
for(int i=;i<=n;i++)
if(dfn[i]==)Tarjan(i);
printf("\n");
for(int u=;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=;i<=N;i++)SPFA(i);
//Dfs(i,i,0);
int mxx=;
for(int i=;i<=m;i++){
u=bl[E[i].u];v=bl[E[i].v];
if(mx[u][v]>mxx){
mxx=mx[u][v];
cnt=;ans[++cnt]=i;
}
else if(mx[u][v]==mxx)
ans[++cnt]=i;
}
printf("%d\n%d\n",mxx,cnt);
for(int i=;i<=cnt;i++)
printf("%d ",ans[i]);
return ;
}
11.12 noip模拟试题的更多相关文章
- 11.14 noip模拟试题
题目名称 正确答案 序列问题 长途旅行 英文名称 answer sequence travel 输入文件名 answer.in sequence.in travel.in 输出文件名 answer ...
- 11.9 noip模拟试题
NOIP2016 模拟赛——那些年,我们学过的文化课背单词(word.c/cpp/pas)[题目描述]fqk 退役后开始补习文化课啦, 于是他打开了英语必修一开始背单词. 看着满篇的单词非常头疼, 而 ...
- 11.13 noip模拟试题
题目名称 笔记 括号 城堡可执行文件名 note brackets castle输入文件名 note.in brackets.in castle.in输出文件名 note.in brackets.ou ...
- 11.10 noip模拟试题
1.第K小数 (number.cpp/c/pas) [问题描述] 有两个正整数数列,元素个数分别为N和M.从两个数列中分别任取一个数 相乘,这样一共可以得到N*M个数,询问这N*M个数中第K小数是多少 ...
- 11.7 NOIP模拟赛
目录 2018.11.7 NOIP模拟 A 序列sequence(two pointers) B 锁lock(思路) C 正方形square(埃氏筛) 考试代码 B C 2018.11.7 NOIP模 ...
- 11/1 NOIP 模拟赛
11.1 NOIP 模拟赛 期望得分:50:实际得分:50: 思路:暴力枚举 + 快速幂 #include <algorithm> #include <cstring> #in ...
- 10.11 noip模拟试题
4题均为128M,1s 1. 锻炼计划(exercise.pas) 身体是革命的本钱,OIers不要因为紧张的学习和整天在电脑前而忽视了健康问题.小x设计了自己的锻炼计划,但他不知道这个计划是否可行, ...
- 9.27 noip模拟试题
工资 (money/money.in/money.out) 时限1000ms 内存256MB 聪哥在暑假参加了打零工的活动,这个活动分为n个工作日,每个工作日的工资为Vi.有m个结算工钱的时间,聪哥可 ...
- 10.27 noip模拟试题
1.铺瓷砖(tile.cpp/c/pas)[问题描述]有一面很长很长的墙. 你需要在这面墙上贴上两行瓷砖. 你的手头有两种不同尺寸的瓷砖,你希望用这两种瓷砖各贴一行.瓷砖的长可以用分数表示,贴在第一行 ...
随机推荐
- 灰度图像--图像增强 直方图均衡化(Histogram equalization)
灰度图像--图像增强 直方图均衡化(Histogram equalization) 转载请标明本文出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些 ...
- 【session】
users.json { "tobi": { "password": "ferret", "name": "T ...
- SharePoint 2010顶部链接导航栏的详细操作
转:http://www.360sps.com/Item/UseTopLink.aspx 在SharePoint 2010环境的页面中,导航链接总体上可以分为两类,一类是显示在左侧的快速启动栏,另一类 ...
- CPU acceleration status:HAXM must be updated(version 1.1.1<6.0.1)
终于上手as了,感觉很爽 但是感觉也特闹心啊 还好有stackoverflow(这特么才是一个神奇的网站好吗) 废话少说 记录一下: 前面历经的磨难暂时不说了,就这个CPU acceleration ...
- LoadRunner中的参数与变量
在LoadRunner脚本开发中,经常会遇到参数与变量相互转换的情况,本文对常见的转换情形进行了方法总结. 1.变量的赋值 //将字符串赋值给变量 ]; strcpy(strTemp, "H ...
- 提高IIS的并发量
IIS 7.0使用的是默认配置,服务器最多只能处理5000个同时请求. 根据相关文档调整设置,可以让服务器从设置上支持10万个同时请求 . 调整IIS 7应用程序池队列长度 由原来的默认1000改为6 ...
- Linux学习笔记31——网络信息
一 主机数据库函数 #include <netdb.h> struct hostent *gethostbyaddr(const void *addr, //地址 size_t len, ...
- 删除顺序链表中重复的数 (一) leecode
Given a sorted linked list, delete all duplicates such that each element appear only once. For examp ...
- 彻底理解position与anchorPoint - Wonderffee's Blog(转)
引言 相信初接触到CALayer的人都会遇到以下几个问题: 为什么修改anchorPoint会移动layer的位置?CALayer的position点是哪一点呢?anchorPoint与positio ...
- mysql添加用户权限
MySQL性能调优my.cnf详解 //登录MYSQLmysql -u root -p//创建用户insert into mysql.user(Host,User,Password) values(‘ ...