A

Description

给一个 01 串设为其 S,询问是否存在只出现两次的 01 串 T。

这里的出现定义为存在一串下标 ,满足  且 

Input

一行,一个 01 串

Output

一行,字母 Y 表示存在,N 表示不存在

HINT

1.设串 S 的长度为 n,

2.设串 S 的长度为 n,

3.设串 S 的长度为 n,

4.数据为随机生成。

对于第一部分,随意骗一骗分?

 #include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
char s[],num0,num1;
int main()
{
scanf("%s",s);
int len=strlen(s);
for(int i=;i<len;i++)
if(s[i]=='')num0++;
else num1++;
if((num0%&&num1%)||num0==||num1==)printf("N");
else printf("Y");
return ;
}

对于第二部分,暴力dfs。

 #include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=<<;
int n,a[],calc[][N];
char s[];
bool f;
int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(x=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
void dfs(int x,int sum,int num,int k)
{
sum=sum*+a[x];
if(a[x]||k)k=;
else num++;
calc[num][sum]++;
for(int i=x+;i<=n;i++)dfs(i,sum,num,k);
}
int main()
{
scanf("%s",s);
n=strlen(s);
for(int i=;i<n;i++)a[i+]=s[i]-'';
for(int i=;i<=n;i++)dfs(i,,,);
int summ=<<n;
for(int i=;i<=n;i++)
for(int j=;j<summ;j++)
if(calc[i][j]==){f=true;break;}
if(f)printf("Y");
else printf("N");
return ;
}

对于第三部分,注意特判0和1的个数恰好为2的情况。

对于其他情况,若存在形如abcd(a!=b,b==c,c!=d)(即0110或1001)类型的子串,则输出Y:此时T为 b前面的所有数字+b(也是c)+后面的所有数字。若不存在,则输出N:对于相邻相同数字长度超过2的子串,在T中必定是全部出现,否则会出现3种及3种以上情况,不满足T的要求;对于相邻数字互不相同的子串,不管怎么选只有一种或多种情况,不满足出现次数恰好为2,此时对于这部分子串倾向于全选(保持出现次数小于2)。

 #include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,zero;
char s[];
bool f;
int main()
{
scanf("%s",s+);
n=strlen(s+);
for(int i=;i<=n;i++)
if(s[i]=='')zero++;
if(zero==||n-zero==)f=true;
for(int i=;i<n-;i++)
if(s[i]!=s[i+]&&s[i+]==s[i+]&&s[i+]!=s[i+])f=true;
if(f)printf("Y");
else printf("N");
return ;
}

B

Description

给长度为 n 的数列 A 和长度为 m 的数列 B,问有多少长度为 m 的数列 C 满足

Input

第一行俩整数 n 和 m

第二行 n 个整数 ,表示数列 A

第三行 m 个整数 ,表示数列 B

Output

一个整数,表示满足条件的数列 C 的个数模  后的值。

HINT

1.        

2.        

3.        

对于第一部分,比赛时暴力dfs。(不要问我为什么不写dp

 #include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,ans,a[],b[];
int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(x=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
void dfs(int x,int deep)
{
if(m-deep>n-x)return;
if(deep==m){ans++;return;}
for(int i=x+;i<=n;i++)
if(a[i]-a[x]+b[deep]>=)dfs(i,deep+);
}
int main()
{
n=read();m=read();
for(int i=;i<=n;i++)a[i]=read();
for(int i=;i<=m;i++)b[i]=read();
if(m==){printf("%d",n);return ;}
for(int i=;i<m;i++)b[i]=b[i+]-b[i];
for(int i=;i<=n;i++)dfs(i,);
printf("%d",ans);
return ;
}

对于第二、三部分,dp+树状数组。

为了方便操作,先进行离散化。num数组是一个队列,存的是原数列离散化后的编号所对应的原值(下标为1~cnt);id[i]代表原数列中下标为i的数字离散化后的编号。

每次都枚举b[i]并重新计算g数组(g[j]代表满足num[k]+b[i-1]<=num[j]+b[i]中k的最大值)。

然后就是愉快的单点修改区间查询了√

 #include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=;
const int mod=1e9+;
int n,m,cnt,ans;
int b[N],id[N],num[N],t[N],f[N],g[N];
struct node{int w,pos;}a[N];
int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(x=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
bool cmp(node a,node b){return a.w<b.w;}
int lowbit(int x){return x&-x;}
void insert(int x,int v)
{
while(x<=n)
{
t[x]=(t[x]+v)%mod;
x+=lowbit(x);
}
}
int query(int x)
{
int ans=;
while(x)
{
ans=(ans+t[x])%mod;
x-=lowbit(x);
}
return ans;
}
int main()
{
n=read();m=read();
for(int i=;i<=n;i++)
a[i].w=read(),a[i].pos=i,f[i]=;
sort(a+,a+n+,cmp);
for(int i=;i<=n;i++)
if(a[i].w==a[i-].w)id[a[i].pos]=cnt;
else id[a[i].pos]=++cnt,num[cnt]=a[i].w;
for(int i=;i<=m;i++)b[i]=read();
for(int i=;i<=m;i++)
{
for(int j=;j<=cnt;j++)
{
int u=g[j-];
while(u<cnt&&num[u+]+b[i-]<=num[j]+b[i])u++;
g[j]=u;
}
memset(t,,sizeof(t));
insert(id[i-],f[i-]);
for(int j=i;j<=n;j++)
{
int sum=f[j];
f[j]=query(g[id[j]]);
insert(id[j],sum);
}
}
for(int i=m;i<=n;i++)ans=(ans+f[i])%mod;
printf("%d",ans);
return ;
}

C

Description

给一个图,n 个点 m 条双向边,每条边有其长度。n 个点中有 k 个是特殊点,问任意两个特殊点的最短路是多少。

Input

第一行三个整数 n m k

第二行 k 个整数 ,为各个特殊点

接下来 m 行,每行三个整数 x y d,表示 x 到 y 有一条长度为 d 的边

Output

一个整数

HINT

1.                

2.                

3.                

4.图为联通图

对于第一部分,Floyd水过。(注意重边和自环!)

 #include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,k,x,y,d,t,ans=inf;
int dis[][];
bool f[];
int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(x=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int main()
{
n=read();m=read();k=read();
for(int i=;i<=k;i++)
{
t=read();
f[t]=true;
}
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(i!=j)dis[i][j]=inf;
for(int i=;i<=m;i++)
{
x=read();y=read();d=read();
dis[x][y]=dis[y][x]=min(dis[x][y],d);
if(f[x]&&f[y]&&x!=y)ans=min(ans,dis[x][y]);
}
for(int k=;k<=n;k++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(dis[i][j]>dis[i][k]+dis[k][j] )
{
dis[i][j]=dis[i][k]+dis[k][j];
if(f[i]&&f[j])ans=min(ans,dis[i][j]);
}
printf("%d",ans);
return ;
}

对于第二部分,跑k次SPFA。

 #include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=;
const int inf=0x3f3f3f3f;
int n,m,k,x,y,t,cnt,ans=inf;
int first[N],a[N],dis[N],q[N];
bool f[N],in[N];
struct edge{int next,to,w;}e[N*];
int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(x=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
void ins(int x,int y,int w){cnt++;e[cnt].to=y;e[cnt].w=w;e[cnt].next=first[x];first[x]=cnt;}
void spfa(int S)
{
memset(in,,sizeof(in));
memset(dis,0x3f,sizeof(dis));
int head=,tail=;
q[]=S;in[S]=true;dis[S]=;
while(head!=tail)
{
int u=q[head++];in[u]=false;
if(head>)head=;
for(int i=first[u];i;i=e[i].next)
{
int v=e[i].to;
if(dis[u]+e[i].w<dis[v])
{
dis[v]=dis[u]+e[i].w;
if(f[v])ans=min(ans,dis[v]);
if(!in[v]){q[tail++]=v;in[v]=true;if(tail>)tail=;}
}
}
}
}
int main()
{
n=read();m=read();k=read();
for(int i=;i<=k;i++)a[i]=read(),f[a[i]]=true;
for(int i=;i<=m;i++)
{
x=read();y=read();t=read();
ins(x,y,t);ins(y,x,t);
}
for(int i=;i<=k;i++)spfa(a[i]);
printf("%d",ans);
return ;
}

对于第三部分,对于每个点,维护以下信息:离它最近的特殊点及路程,离它次近的特殊点及路程(且需保证两个特殊点不同)。最后再枚举点,用最短路+次短路来更新答案。(看到好多大佬都是枚举边……瑟瑟发抖。

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int N=;
const int inf=0x3f3f3f3f;
int n,m,k,cnt,x,y,w,ans=inf;
int a[],first[N],fir[N],sec[N],firn[N],secn[N];
struct edge{int to,next,w;}e[N*];
struct node
{
int d,id;
bool operator <(const node& x)const{return x.d<d;}
};
priority_queue<node>q;
int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(x=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
void ins(int x,int y,int w)
{
cnt++;e[cnt].to=y;e[cnt].w=w;
e[cnt].next=first[x];first[x]=cnt;
}
void dijkstra()
{
memset(fir,0x3f,sizeof(fir));
memset(sec,0x3f,sizeof(sec));
for(int i=;i<=k;i++)
{
fir[a[i]]=;firn[a[i]]=a[i];
q.push((node){,a[i]});
}
while(!q.empty())
{
node x=q.top();q.pop();
if(x.d>fir[x.id])continue;
int now=x.id;
for(int i=first[now];i;i=e[i].next)
{
int to=e[i].to;
if(firn[now]==firn[to])
{
if(fir[now]+e[i].w<fir[to])
fir[to]=fir[now]+e[i].w,q.push((node){fir[to],to});
}
else if(fir[now]+e[i].w<fir[to])
{
sec[to]=fir[to];secn[to]=firn[to];
fir[to]=fir[now]+e[i].w;firn[to]=firn[now];
q.push((node){fir[to],to});
// printf("[fir]%d %d %d [n] %d %d\n",now,to,fir[to],firn[now],firn[to]);
}
else if(fir[now]+e[i].w<sec[to])
{
sec[to]=fir[now]+e[i].w;
secn[to]=firn[now];
// printf("[sec]%d %d %d [n] %d %d\n",now,to,sec[to],secn[now],secn[to]);
}
}
}
}
int main()
{
n=read();m=read();k=read();
for(int i=;i<=k;i++)a[i]=read();
for(int i=;i<=m;i++)
{
x=read();y=read();w=read();
ins(x,y,w);ins(y,x,w);
}
dijkstra();
for(int i=;i<=n;i++)ans=min(ans,fir[i]+sec[i]);
printf("%d",ans);
return ;
}

【解题报告】SRM-08的更多相关文章

  1. 【九度OJ】题目1475:IP数据包解析 解题报告

    [九度OJ]题目1475:IP数据包解析 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1475 题目描述: 我们都学习过计算机网络, ...

  2. 【LeetCode】378. Kth Smallest Element in a Sorted Matrix 解题报告(Python)

    [LeetCode]378. Kth Smallest Element in a Sorted Matrix 解题报告(Python) 标签: LeetCode 题目地址:https://leetco ...

  3. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

  4. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

  5. BZOJ 1051 最受欢迎的牛 解题报告

    题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4438  Solved: 2353[S ...

  6. 习题:codevs 2822 爱在心中 解题报告

    这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...

  7. 习题:codevs 1035 火车停留解题报告

    本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...

  8. 习题: codevs 2492 上帝造题的七分钟2 解题报告

    这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...

  9. 习题:codevs 1519 过路费 解题报告

    今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...

  10. NOIP2016提高组解题报告

    NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合

随机推荐

  1. EEPROM

    EEPROM (Electrically Erasable Programmable read only memory),带电可擦可编程只读存储器--一种掉电后数据不丢失的存储芯片. EEPROM 可 ...

  2. 通俗易懂的来理解Iaas,Paas,SaaS

    首先我们先来了解一下这几个单词的意思和完全的英文 Iaas:Infrastructure as a service    基础设施即服务 Paas:Platform as a service   平台 ...

  3. Arch更新时failed to prepare transaction

    error: failed to prepare transaction (could not satisfy dependencies) :: ffmpeg2.8: installing x265 ...

  4. Session 常见操作

    对于敏感.重要的信息,建议要存储在服务器端(Session是存储在服务器端的),不能存储在浏览器中,如用户名.余额.等级.验证码等信息 Session依赖于Cookie session数据的获取 se ...

  5. React之Perf

    import Perf from 'react-addons-perf' // ES6语法 var Perf = require('react-addons-perf') // ES5语法针对node ...

  6. latex 双引号 “

    别在latex敲,在记事本上敲完后,拷贝到latex中.

  7. bcftools或vcftools提取指定区段的vcf文件(extract specified position )

    下载安装bcftools 见如下命令: bcftools filter 1000Genomes.vcf.gz --regions 9:4700000-4800000 > 4700000-4800 ...

  8. Day23--Python--常用模块02--序列化,configparser

    1. 序列化 把对象打散成bytes或者字符串. 方便存储和传输 序列化 把bytes或者字符串转换回对象. 反序列化 2. pickle(比较重要) 把python中所有的对象都可以转化成bytes ...

  9. python学习笔记-Day2 Numpy数组

    1. 实现两个数组相加,在数据量特别大的时候 产生数组: (1)  从列表产生数组:a=[0,1,2,3] a=np.array(1) a (2)  从列表传入 a=np.array([1,2,3,4 ...

  10. phpstudy vhosts.conf 文件配置 记录下!

    <VirtualHost _default_:80>DocumentRoot "D:\phpStudy\WWW" <Directory "D:\phpS ...