【SRM-08】解题报告

A

Description

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

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

Input

一行,一个 01 串

Output

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

HINT

1.设串 S 的长度为 n,

2.设串 S 的长度为 n,

3.设串 S 的长度为 n,

4.数据为随机生成。

对于第一部分,打个表骗分。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 char s[5],num0,num1;
 6 int main()
 7 {
 8     scanf("%s",s);
 9     int len=strlen(s);
10     for(int i=0;i<len;i++)
11         if(s[i]==‘0‘)num0++;
12         else num1++;
13     if((num0%2&&num1%2)||num0==3||num1==3)printf("N");
14     else printf("Y");
15     return 0;
16 }

对于第二部分,暴力dfs。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 const int N=1<<12;
 6 int n,a[15],calc[15][N];
 7 char s[15];
 8 bool f;
 9 int read()
10 {
11     int x=0,f=1;char c=getchar();
12     while(c<‘0‘||c>‘9‘){if(x==‘-‘)f=-1;c=getchar();}
13     while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
14     return x*f;
15 }
16 void dfs(int x,int sum,int num,int k)
17 {
18     sum=sum*2+a[x];
19     if(a[x]||k)k=1;
20     else num++;
21     calc[num][sum]++;
22     for(int i=x+1;i<=n;i++)dfs(i,sum,num,k);
23 }
24 int main()
25 {
26     scanf("%s",s);
27     n=strlen(s);
28     for(int i=0;i<n;i++)a[i+1]=s[i]-‘0‘;
29     for(int i=1;i<=n;i++)dfs(i,0,0,0);
30     int summ=1<<n;
31     for(int i=0;i<=n;i++)
32         for(int j=0;j<summ;j++)
33             if(calc[i][j]==2){f=true;break;}
34     if(f)printf("Y");
35     else printf("N");
36     return 0;
37 }

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

对于其他情况,若存在形如abcd(a!=b,b==c,c!=d)(即0110或1001)类型的子串,则输出Y。此时T为 b前面的所有数字+b(也是c)+后面的所有数字。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 int n,zero;
 6 char s[5010];
 7 bool f;
 8 int main()
 9 {
10     scanf("%s",s+1);
11     n=strlen(s+1);
12     for(int i=1;i<=n;i++)
13         if(s[i]==‘0‘)zero++;
14     if(zero==2||n-zero==2)f=true;
15     for(int i=0;i<n-1;i++)
16         if(s[i]!=s[i+1]&&s[i+1]==s[i+2]&&s[i+2]!=s[i+3])f=true;
17     if(f)printf("Y");
18     else printf("N");
19     return 0;
20 }

B

Description

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

Input

第一行俩整数 n 和 m

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

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

Output

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

HINT

1.        

2.        

3.        

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

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 int n,m,ans,a[55],b[10];
 6 int read()
 7 {
 8     int x=0,f=1;char c=getchar();
 9     while(c<‘0‘||c>‘9‘){if(x==‘-‘)f=-1;c=getchar();}
10     while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
11     return x*f;
12 }
13 void dfs(int x,int deep)
14 {
15     if(m-deep>n-x)return;
16     if(deep==m){ans++;return;}
17     for(int i=x+1;i<=n;i++)
18         if(a[i]-a[x]+b[deep]>=0)dfs(i,deep+1);
19 }
20 int main()
21 {
22     n=read();m=read();
23     for(int i=1;i<=n;i++)a[i]=read();
24     for(int i=1;i<=m;i++)b[i]=read();
25     if(m==1){printf("%d",n);return 0;}
26     for(int i=1;i<m;i++)b[i]=b[i+1]-b[i];
27     for(int i=1;i<=n;i++)dfs(i,1);
28     printf("%d",ans);
29     return 0;
30 }

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

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 const int N=2010;
 6 const int mod=1e9+7;
 7 int n,m,cnt,ans;
 8 int b[N],id[N],num[N],t[N],f[N],g[N];
 9 struct node{int w,pos;}a[N];
10 int read()
11 {
12     int x=0,f=1;char c=getchar();
13     while(c<‘0‘||c>‘9‘){if(x==‘-‘)f=-1;c=getchar();}
14     while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
15     return x*f;
16 }
17 bool cmp(node a,node b){return a.w<b.w;}
18 int lowbit(int x){return x&-x;}
19 void insert(int x,int v)
20 {
21     while(x<=n)
22     {
23         t[x]=(t[x]+v)%mod;
24         x+=lowbit(x);
25     }
26 }
27 int query(int x)
28 {
29     int ans=0;
30     while(x)
31     {
32         ans=(ans+t[x])%mod;
33         x-=lowbit(x);
34     }
35     return ans;
36 }
37 int main()
38 {
39     n=read();m=read();
40     for(int i=1;i<=n;i++)
41         a[i].w=read(),a[i].pos=i,f[i]=1;
42     sort(a+1,a+n+1,cmp);
43     for(int i=1;i<=n;i++)
44         if(a[i].w==a[i-1].w)id[a[i].pos]=cnt;
45         else id[a[i].pos]=++cnt,num[cnt]=a[i].w;
46     for(int i=1;i<=m;i++)b[i]=read();
47     for(int i=2;i<=m;i++)
48     {
49         for(int j=1;j<=cnt;j++)
50         {
51             int u=g[j-1];
52             while(u<cnt&&num[u+1]+b[i-1]<=num[j]+b[i])u++;
53             g[j]=u;
54         }
55         memset(t,0,sizeof(t));
56         insert(id[i-1],f[i-1]);
57         for(int j=i;j<=n;j++)
58         {
59             int sum=f[j];
60             f[j]=query(g[id[j]]);
61             insert(id[j],sum);
62         }
63     }
64     for(int i=m;i<=n;i++)ans=(ans+f[i])%mod;
65     printf("%d",ans);
66     return 0;
67 }

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水过。(注意重边和自环)

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 const int inf=0x3f3f3f3f;
 6 int n,m,k,x,y,d,t,ans=inf;
 7 int dis[305][305];
 8 bool f[305];
 9 int read()
10 {
11     int x=0,f=1;char c=getchar();
12     while(c<‘0‘||c>‘9‘){if(x==‘-‘)f=-1;c=getchar();}
13     while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
14     return x*f;
15 }
16 int main()
17 {
18     n=read();m=read();k=read();
19     for(int i=1;i<=k;i++)
20     {
21         t=read();
22         f[t]=true;
23     }
24     for(int i=1;i<=n;i++)
25         for(int j=1;j<=n;j++)
26             if(i!=j)dis[i][j]=inf;
27     for(int i=1;i<=m;i++)
28     {
29         x=read();y=read();d=read();
30         dis[x][y]=dis[y][x]=min(dis[x][y],d);
31         if(f[x]&&f[y]&&x!=y)ans=min(ans,dis[x][y]);
32     }
33     for(int k=1;k<=n;k++)
34         for(int i=1;i<=n;i++)
35             for(int j=1;j<=n;j++)
36                 if(dis[i][j]>dis[i][k]+dis[k][j] )
37                  {
38                      dis[i][j]=dis[i][k]+dis[k][j];
39                      if(f[i]&&f[j])ans=min(ans,dis[i][j]);
40                  }
41     printf("%d",ans);
42     return 0;
43 }

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

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 const int N=100010;
 6 const int inf=0x3f3f3f3f;
 7 int n,m,k,x,y,t,cnt,ans=inf;
 8 int first[N],a[N],dis[N],q[N];
 9 bool f[N],in[N];
10 struct edge{int next,to,w;}e[N*2];
11 int read()
12 {
13     int x=0,f=1;char c=getchar();
14     while(c<‘0‘||c>‘9‘){if(x==‘-‘)f=-1;c=getchar();}
15     while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
16     return x*f;
17 }
18 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;}
19 void spfa(int S)
20 {
21     memset(in,0,sizeof(in));
22     memset(dis,0x3f,sizeof(dis));
23     int head=0,tail=1;
24     q[0]=S;in[S]=true;dis[S]=0;
25     while(head!=tail)
26     {
27         int u=q[head++];in[u]=false;
28         if(head>100000)head=0;
29         for(int i=first[u];i;i=e[i].next)
30         {
31             int v=e[i].to;
32             if(dis[u]+e[i].w<dis[v])
33             {
34                 dis[v]=dis[u]+e[i].w;
35                 if(f[v])ans=min(ans,dis[v]);
36                 if(!in[v]){q[tail++]=v;in[v]=true;if(tail>100000)tail=0;}
37             }
38         }
39     }
40 }
41 int main()
42 {
43     n=read();m=read();k=read();
44     for(int i=1;i<=k;i++)a[i]=read(),f[a[i]]=true;
45     for(int i=1;i<=m;i++)
46     {
47         x=read();y=read();t=read();
48         ins(x,y,t);ins(y,x,t);
49     }
50     for(int i=1;i<=k;i++)spfa(a[i]);
51     printf("%d",ans);
52     return 0;
53 }

对于第三部分,对于每个点,维护以下信息:离它最近的特殊点及路程,离它次近的特殊点及路程(且需保证两个特殊点不同)。最后再扫一遍,用最短路+次短路来更新答案。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<queue>
 5 using namespace std;
 6 const int N=100010;
 7 const int inf=0x3f3f3f3f;
 8 int n,m,k,cnt,x,y,w,ans=inf;
 9 int a[10010],first[N],fir[N],sec[N],firn[N],secn[N];
10 struct edge{int to,next,w;}e[N*6];
11 struct node
12 {
13     int d,id;
14     bool operator <(const node& x)const{return x.d<d;}
15 };
16 priority_queue<node>q;
17 int read()
18 {
19     int x=0,f=1;char c=getchar();
20     while(c<‘0‘||c>‘9‘){if(x==‘-‘)f=-1;c=getchar();}
21     while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
22     return x*f;
23 }
24 void ins(int x,int y,int w)
25 {
26     cnt++;e[cnt].to=y;e[cnt].w=w;
27     e[cnt].next=first[x];first[x]=cnt;
28 }
29 void dijkstra()
30 {
31     memset(fir,0x3f,sizeof(fir));
32     memset(sec,0x3f,sizeof(sec));
33     for(int i=1;i<=k;i++)
34     {
35         fir[a[i]]=0;firn[a[i]]=a[i];
36         q.push((node){0,a[i]});
37     }
38     while(!q.empty())
39     {
40         node x=q.top();q.pop();
41         if(x.d>fir[x.id])continue;
42         int now=x.id;
43         for(int i=first[now];i;i=e[i].next)
44         {
45             int to=e[i].to;
46             if(firn[now]==firn[to])
47             {
48                 if(fir[now]+e[i].w<fir[to])
49                     fir[to]=fir[now]+e[i].w,q.push((node){fir[to],to});
50             }
51             else if(fir[now]+e[i].w<fir[to])
52             {
53                 sec[to]=fir[to];secn[to]=firn[to];
54                 fir[to]=fir[now]+e[i].w;firn[to]=firn[now];
55                 q.push((node){fir[to],to});
56 //                printf("[fir]%d %d %d [n] %d %d\n",now,to,fir[to],firn[now],firn[to]);
57             }
58             else if(fir[now]+e[i].w<sec[to])
59             {
60                 sec[to]=fir[now]+e[i].w;
61                 secn[to]=firn[now];
62 //                printf("[sec]%d %d %d [n] %d %d\n",now,to,sec[to],secn[now],secn[to]);
63             }
64         }
65     }
66 }
67 int main()
68 {
69     n=read();m=read();k=read();
70     for(int i=1;i<=k;i++)a[i]=read();
71     for(int i=1;i<=m;i++)
72     {
73         x=read();y=read();w=read();
74         ins(x,y,w);ins(y,x,w);
75     }
76     dijkstra();
77     for(int i=1;i<=n;i++)ans=min(ans,fir[i]+sec[i]);
78     printf("%d",ans);
79     return 0;
80 }

时间: 2024-10-24 00:24:03

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

topcoder srm 623解题报告

详见:http://robotcator.logdown.com/posts/231132-topcoder-srm-623 推荐使用插件greed 2.0,非常使用的插件.但我不知道如何自己添加测试数据,下次再学习下. Greed 2.0 https://github.com/shivawu/topcoder-greed 250pt 题意:环形跑道上有n棵树,标号为1--n,Alice跑步时记录下一些树的标号.问通过这些编号计算她最少跑了多少圈. 题解:稍微想一下就知道,一圈下来树的编号都是递

08年acm区域赛北京赛区 部分题解题报告

08年区域赛北京赛区 http://poj.org/searchproblem?field=source&key=Beijing+2008 POJ 3921 Destroying the bus stations 题目还是比较难的,当时的榜似乎只有4/25的通过/提交,其实题目数据很水.学长转换模型写了网络流求最小割,可以AC,不过自己造了个数据推翻了正确性.我写了个很挫的bfs套bfs,外层是最小的删除点数,内层是求最短路,数据很水可以AC.但比较蛋疼的在于bfs耗内存,而且队列中的点数是阶乘

Codeforces Round #259 (Div. 2) 解题报告

终于重上DIV1了.... A:在正方形中输出一个菱形 解题代码: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2014年08月01日 星期五 23时27分55秒 4 5 #include<vector> 6 #include<set> 7 #include<deque> 8 #include<stack> 9 #include<bitset> 10 #inclu

Codeforces 459(#261 (Div. 2) ) 解题报告

A:给你一个正方形的两点,让你求其余亮点 解法:乱搞 解题代码: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2014年08月15日 星期五 23时24分04秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<

HDU4911 Inversion 解题报告

题意:求逆序对 解题思路:1)树状数组 + 离散化 解题代码: 1 // File Name: a.cpp 2 // Author: darkdream 3 // Created Time: 2014年08月05日 星期二 12时05分09秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<

解题报告 之 POJ3057 Evacuation

解题报告 之 POJ3057 Evacuation Description Fires can be disastrous, especially when a fire breaks out in a room that is completely filled with people. Rooms usually have a couple of exits and emergency exits, but with everyone rushing out at the same time

hdu 1541 Stars 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1541 题目意思:有 N 颗星星,每颗星星都有各自的等级.给出每颗星星的坐标(x, y),它的等级由所有比它低层(或者同层)的或者在它左手边的星星数决定.计算出每个等级(0 ~ n-1)的星星各有多少颗. 我只能说,题目换了一下就不会变通了,泪~~~~ 星星的分布是不是很像树状数组呢~~~没错,就是树状数组题来滴! 按照题目输入,当前星星与后面的星星没有关系.所以只要把 x 之前的横坐标加起来就可以了

【百度之星2014~初赛(第二轮)解题报告】Chess

声明 笔者最近意外的发现 笔者的个人网站http://tiankonguse.com/ 的很多文章被其它网站转载,但是转载时未声明文章来源或参考自 http://tiankonguse.com/ 网站,因此,笔者添加此条声明. 郑重声明:这篇记录<[百度之星2014~初赛(第二轮)解题报告]Chess>转载自 http://tiankonguse.com/ 的这条记录:http://tiankonguse.com/record/record.php?id=667 前言 最近要毕业了,有半年没做

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh童鞋的提醒. 勘误2:第7题在推断连通的时候条件写错了,后两个if条件中是应该是<=12 落了一个等于号.正确答案应为116. 1.煤球数目 有一堆煤球.堆成三角棱锥形.详细: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第四层10个(排列成三角形). -. 假设一共

[noip2011]铺地毯(carpet)解题报告

最近在写noip2011的题,备战noip,先给自己加个油! 下面是noip2011的试题和自己的解题报告,希望对大家有帮助,题目1如下 1.铺地毯(carpet.cpp/c/pas) [问题描述]为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有n 张地毯,编号从1 到n.现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上.地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的