noip模拟题 11.2
2016-11-02 19:51
253 查看
T1 神秘大门
【题目描述】
最近小K大牛经过调查发现,在WZland的最南方——WZ Antarctica 出现了奇怪的磁场反应。为了弄清楚这一现象,小K 大牛亲自出马,来到了WZ Antarctica。
小K大牛发现WZ Antarctica 出现了一道神秘的大门。人总有好奇心,小K大牛想打开这扇神秘大门,看门的后面究竟是什么东西,但用尽什么办法也不能打开这扇门。
突然,门上出现了一些奇怪的字符。凭着敏锐的直觉,小K 认为这些符号就是打开这扇门的关键, 于是小K 抓紧时间开始研究这些符号。
经过一些时间的研究,小K 大牛发现这些符号其实是一串密码,只有破解了这个密码, 才能打开那扇神秘大门。这个密码十分简单,他给出了两个很长的字符串A 和B,你只需要判断B 是否在A 中出现过就可以了,当然如果B 在A中出现,那么你还需要输出B 的字符在A 中依次出现的位置。这里解释一下B 在A 中出现的概念,设A=S1S2…SN,B= T1T2…TM,如果存在一组数K:K1<K2<…<KM,使得B=SK1SK2…SKM,那么就可以认为B 在A 出现过。比如说A=sdfesad, B=sfsad,那么B 在A 中出现过,因为B 中的字符在A中依次出现的位置为1 3 5 6 7。
这个解密过程实在太简单了,于是小K 大牛就将这个任务交给了你。由于小K大牛十分着急,他只给了你1s 的时间。
【输入】
输入数据包含2 行,分别包含一个字符串,第一行输入的是字符串A,第二行输入的是字符串B。【输出】
第一行输出一个字符串“Yes”或“No”,如果B 在A 中出现,那么输出“Yes”,否则输出“No”。如果你的第一行输出“Yes”,那么在第接下来若干行你需要输出一组数K,使得B=SK1SK2…SKM,每行一个数;否则第二行为空。如果存在多组数据满足条件,你需要输出字典序最大的一组。
【输入输出样例1】
输入:sdfesad
sfsad
输出:
Yes
1
3
5
6
7
【输入输出样例2】
输入:abcdef
acdefg
输出
No
水题,一开始想的是用两个指针对应 A B 串的下标,枚举即可。需要注意的是要输出字典序最大的,所以从后往前枚举即可。
代码:
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; char A[1000005],B[1000005]; int ans[1000005],cnt; int main() { freopen("door.in","r",stdin); freopen("door.out","w",stdout); scanf("%s",A); scanf("%s",B); int lena=strlen(A),lenb=strlen(B); int i=lena-1,j=lenb-1; while(i>=0) { if(A[i]==B[j]) { i--; j--; ans[++cnt]=i+2; } else i--; if(j==-1) { printf("Yes\n"); for(int k=cnt;k>=1;k--) printf("%d\n",ans[k]); return 0; } } printf("No"); return 0; }
T2 集结蚂蚁
【题目描述】
雄心勃勃的企业家达伦·克劳斯发现了皮姆博士有关缩小原子间距离的公式并研发出新一代微型“黄蜂战士”,皮姆博士担忧武器会引发不可挽回的后果,于是找到斯科特并使他成为了新一代“蚁人”。正逢克劳斯与外商交易黄蜂战衣的那天,斯科特受命前往摧毁黄蜂战衣并销毁数据,然而一个人的力量是渺小的,斯科特需要走入一个巨大的蚁穴去召唤蚂蚁与他共同作战。
蚁穴是一个巨大复杂的地带,由n 行m 列组成,每个偶数行存在至少一个蚂蚁聚集地,同一行的不同蚂蚁聚集地以一堵墙隔开,每个蚂蚁聚集地的大小为Si;每个奇数行存在连接相邻偶数行中蚂蚁聚集地的路径,一个蚂蚁聚集地可能有多条路径可以到达。
蚁人可从蚁穴的第一行任何一路口出发,由于时间紧迫,蚁人只能向下一行走,在这种情况下,蚁人希望你能告诉他如何使经过的蚂蚁聚集地大小之和最大,从而召唤最多的蚂蚁。
【输入】
第1 行包含两个用空格隔开的整数n,m,意义见描述。第2 到n+1 行,每行m 个字符(无间隔)且仅存在0 和1:同一偶数行中连续x 个0 组成一个大小为x 的蚂蚁聚集地,1 为墙体;奇数行中0 表示蚁人可以从此处通过。
【输出】
对于每组数据输出一个整数,表示经过路径中最大聚集地之和(不包含聚集地之间的路径)。若蚁人无法到达最后一行则请输出“-1”。【输入样例】
10 101111101111
1100001011
1101111111
1100000101
1110110111
1000110001
1101111011
1101000011
1101011111
1101010001
【输出样例】
17【样例解释】
【数据规模】
对于20%的数据,n≤20,m≤20对于50%的数据,n≤20,m≤100
对于100%的数据,n≤5000,m≤2000,保证n 是一个偶数,路径的数量不多于1×10^6
不难想到往下dp,还是很好做的。有一点要注意,到达偶数行时,可以召唤整个蚂蚁聚集地的蚂蚁,而不是走的路径,所以要预处理一下,否则要 T。有大神用建图做。
好吧这题我被卡常了,T 了两个点。生平第一次被卡常,很不爽。
代码:
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int dp[5001][2001],n,m,tmp[2001]; int map[5001][2001]; int main() { freopen("ant.in","r",stdin); freopen("ant.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { bool tttt=false; if(i&1==1)tttt=true; getchar(); for(int j=1;j<=m;j++) { char c; scanf("%c",&c); if(c=='1') map[i][j]=-1; ca9e else { if(tttt==false) map[i][j]=1; else map[i][j]=0; } } } memset(dp,128,sizeof(dp)); for(int i=1;i<=m;i++) if(map[1][i]==0) dp[1][i]=0; for(int i=2;i<=n;i++) { int tt=-9999,now=-9999,tot=0; for(int j=1;j<=m;j++) { if(map[i][j]==-1) { if(tt>0) { dp[i][j-1]=now+tot; tot=0; now=-9999; tt=-9999; continue; } tot=0; continue; } if(map[i][j]==1) tot++; if(dp[i-1][j]>=now) { now=dp[i-1][j]; tt=j; } if(j==m&&tt) { if(map[i][j]) dp[i][j]=now+tot; else dp[i][j-1]=now+tot; } } for(int j=m;j>=1;j--) if(map[i][j]!=-1) dp[i][j]=max(dp[i][j],dp[i][j+1]); } int ans=-99,l; for(int i=1;i<=m;i++) // if(dp [i]!=n) ans=max(ans,dp [i]); if(ans<0) printf("-1"); else printf("%d",ans); return 0; }
T3 计数
【题目描述】
我们都爱奎奎,最近奎奎给大家出了一道题。他告诉了我们一个n*m 的矩阵点,在这个矩阵中的点可以连接成很多线,求长度等于某一长度的线的条数。
数论学的不好。
我的想法是先打一个表。数据范围是:N<=1000000000;M<=1000000000;T<=100
所以打一个 1…q 的表,内容是 i*i ,大概需要32000的空间,然后每输入一个数,枚举表中的内容,ans+ 就行。另外还加了优化。
但不知为何,要崩溃,访问无效内存…
崩溃代码:
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int ping[1000000],ans[101]; int main() { freopen("amount.in","r",stdin); freopen("amount.out","w",stdout); int n,m,t,cnt=0; for(int i=1;i*i<=1000000000;i++) ping[i]=i*i; scanf("%d%d%d",&n,&m,&t); while(t--) { int x; scanf("%d",&x); ans[++cnt]+=m*(n-x)+(m-x)*n; int q=x*x; int minx=lower_bound(ping+1,ping+31624,q)-ping-1; int low=0x7f7f7f7f; for(int i=1;ping[i]<low;i++) { int tmp=q-ping[i]; for(int j=minx;j;j--) { if(tmp<ping[j]) { minx=j+1;low=ping[j+1]; break; } else if(tmp==ping[j]) { int op=i; int cp=j; ans[cnt]+=(n-op)*(m-cp)*2+(n-cp)*(m-op)*2; minx=j; low=ping[j]; break; } } } } for(int i=1;i<=cnt;i++) printf("%d ",ans[i]); return 0; }
有人知道哪里崩溃了吗??求助。
相关文章推荐
- 11.2 NOIP模拟赛 (morning)
- NOIP模拟题 [DP][二分][树剖][树上差分]
- NOIP模拟题 2016.11.10 [模拟] [状压DP] [线段树] [DFS序]
- xjoi10月17日noip提高组模拟题
- [Noip模拟题]绿豆蛙的归宿
- 【NOIP模拟题】【DFS】【位运算】【舞蹈链】2016.11.12第三题题解
- NOIP 模拟题 排列
- 【NOIP模拟题】【暴力求解法】【JOI】2016.11.14第二题 愉快的logo设计 题解
- 【NOIP模拟题】【数学归纳法】【GCD】2016.11.16 第一题 LGTB 与序列 题解
- [JZOJ5445]【NOIP2017提高A组冲刺11.2】失格
- C++——NOIP模拟题——二叉树
- 【NOIP 模拟题】[山东多校联合模拟赛 day1 T2] 祖先(dp)
- 【NOIP 模拟题】中位数(规律+递推)
- 【NOIP 模拟题】[T1]return(模拟)
- 【NOIP模拟题】“与”(位运算)
- NOIP 模拟题 可接受序列
- noip模拟题10.20
- [NOIP模拟题][高效算法设计][建模][BFS][记忆化搜索]
- NOIP模拟题 2016.11.7 [DP*3]
- NOIP模拟题 [模拟][DP][线段树]