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)[问题描述]有一面很长很长的墙. 你需要在这面墙上贴上两行瓷砖. 你的手头有两种不同尺寸的瓷砖,你希望用这两种瓷砖各贴一行.瓷砖的长可以用分数表示,贴在第一行 ...
随机推荐
- Android ListView中 每一项都有不同的布局
实现代码 Adapter的代码 其中:ViewHolder分别是三个不同的布局,也就是ListView中每一项的布局 TYPE_1...是三种类型. 在使用不同布局的时候,getItemViewTyp ...
- 利用if else 求房贷
static void Main(string[] args) { while (true) //主要就是公式的运用和if else 的嵌套 ...
- zabbix监控redis多实例(low level discovery)
对于多实例部署的tomcat.redis等应用,可以利用zabbix的low level discovery功能来实现监控,减少重复操作. 注:Zabbix版本: Zabbix 3.0.2 一.服务 ...
- 设置SharePoint2010列表的项目级权限
转:http://www.cfanz.cn/?c=article&a=read&id=24096 在SharePoint2010中我们经常会用到这样的权限设置,在一个列表中可以存储多个 ...
- Modifying the ASP.NET Request Queue Limit
Modifying the ASP.NET Request Queue Limit When ASP.NET is queried, the request for service is carrie ...
- Off-by-one错误
在迭代循环中,误用> < ≥ ≤符号,有可能导致循环次数多一次或者少一次,就会引发off-by-one错误,混用半开区间和闭区间时,也经常发生此类错误,解决方法是利用最小的输入值去测试代码 ...
- [TopCoder] SRM_594_DIV2.250
好长一段时间没写博客了,实在是想不出有什么好写的.近期也有对自己的职业做了一点思考,还是整理不出个所以然来,很是烦躁 ... 研究TopCoder已经有一小段时间了,都是在做之前的题目,还没有实际参加 ...
- Linux系统IP地址
1.IP地址概述 2.配置IP地址 查看IP地址 在网卡上绑定一个IP地址 同一张网卡上绑定多个IP 绑定一块网卡设备 修改或删除IP地址 IP地址概述 这里不多赘述,参考<计算机网络>课 ...
- Javascript之<script>标签
把javascript代码插入到HTML页面中需要使用<script>标签,使用这个元素可以使javascript和html标记混合在一个页面中,也可以引入外部的javascript文件. ...
- Kerberos验证过程
参考文献: How the Kerberos Version 5 Authentication Protocol Works: Logon and Authentication SQL Kerbero ...