10.1 test solution.
来源:互联网 发布:比特币挖矿软件最新版 编辑:程序博客网 时间:2024/06/06 01:40
1.a(a.cpp/c/pas)
时间限制
1000ms
空间限制
256MB
【问题描述】
你是能看到第一题的 friends呢。 —— hja
何大爷对字符串十分有研究,于是天出题虐杀 zhx。何大爷今天为字符串定义了新的权值计算方法。一个字符串由小写字母组成,字符串的权值被定义为其中出现次数最多的字符的次数减去少出现次数最少的字符的次数。(注 被定义为其中出现次数最多的字符减去少。(注意,在讨论出现最少的字符的时候该字符必须至少出现一次)现在何大爷给你一个字符串,何大爷想知道这个字符串的所有子串中权值最大的权值是多少?
【输入格式】
第一行 一个整数
接下来一行
【输出格式】
一行个整数代表答案。
【样例输入】
10aabbaaabab
【样例输出】
3
【数据范围与规定】
对于
对于
对于
solution
60分
- 暴力枚举每个字串,对于每个字串更新一次答案。
100分
令
sum[c][i] 表示c 这个字符到i 这个位置出现的次数l 表示子串的左端点,r 表示右端点那对于一个子串他的权值就是
max{sum[c][r]−sum[c][l−1]}−min{sum[c][r]−sum[c][l−1]} ,其中c 是小写字母假设在每个子串中出现次数最多的那个字符为
a ,最小的为b 那
ans=sum[a][r]−sum[a][l−1]−(sum[b][r]−sum[b][l−1]) =sum[a][r]−sum[b][r]+sum[b][l−1]−sum[a][l−1] =sum[a][r]−sum[b][r]−(sum[a][l−1]−sum[b][l−1]) 计算上面那个式子的
max ,需要枚举两个字符a,b 和两个端点l,r 时间复杂度是
O(n2∗262) ,会TLE 先把
262 优化到26 每次移动端点仅仅是新加入一个字符,也就是说只有这一个新加入的字符会影响答案,所以只用这个字符和其余的字符做差然后取绝对值就好了,并不用挨个枚举更新答案
然后再把
n2 优化到n 因为对于最后的答案我们并不在意
l,r ,所以看一下能不能省掉一维状态对于每次右端点的移动,可能它对应的最右的左端点和上次一样
也就是说右端点的移动不一定会让
(sum[a][l−1]−sum[b][l−1]) 的最小值更新所以用一个数组
Min[a][b] 来保存(sum[a][l−1]−sum[b][l−1]) 的最小值然后
sum 数组直接省掉第二维,表示的是到当前右端点字符出现的次数之和假设出现在右端点的字符是
a ,其余的字母是b ,那么每次移动右端点ans=max{sum[a]−sum[b]−Min[a][b],sum[b]−sum[a]−Min[b][a]} 这样来更新还是有BUG的,你还需要记录最后更新
Min[a][b] 的位置和b 最后出现的位置如果这两个位置相同,
sum[a]−sum[b]−Min[a][b] 的值还要再−1 这个东西很好想的,自己想一下就可以想出来,我就不再赘述啦
code
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MAXN 1000010int sum[30],last[30];int Min[30][30],pos[30][30];char s[MAXN];int main() { int n; scanf("%d%s",&n,s+1); int ans=-1; for(int i=1;i<=n;i++) { int a=s[i]-'a'+1; sum[a]++; last[a]=i; for(int b=1;b<=26;b++) if(b!=a&&sum[b]!=0) { ans=max(ans,sum[a]-sum[b]-Min[a][b]-(last[b]==pos[a][b])); ans=max(ans,sum[b]-sum[a]-Min[b][a]-(last[b]==pos[b][a])); } for(int b=1;b<=26;b++) { if(sum[a]-sum[b]<Min[a][b]) { Min[a][b]=sum[a]-sum[b]; pos[a][b]=i; } if(sum[b]-sum[a]<Min[b][a]) { Min[b][a]=sum[b]-sum[a]; pos[b][a]=i; } } } printf("%d",ans); return 0;}
2.b(b.cpp/c/pas)
时间限制
1000ms
空间限制
256MB
【问题描述】
你是能看到第二题的 friends 呢。 ——laekov
Hja 和 Yjq 在玩捉迷藏。Yjq 躲了起来,Hja 要找他。在他们玩游戏的房间里,只有一堵不透明的墙和一个双面的镜子。Hja 和 Yjq 可以看作平面上坐标分别为
如果视线和障碍物有公共点,那么我们认为视线会被阻挡,无法看见。如果视线和镜子有公共点,那么我们认为发生了反射。反射的过程遵循物理规律——入射角等于反射角,且反射光线与入射光线在镜子同侧。也就是说,想要看见对方,Hja 和 Yjq 必须在镜子的同一侧,包括镜子所在直线上(参见样例 1)。如果视线与镜子重合,那么不会发生反射,并且镜子不被当作障碍物(参见样例 4)。
Hja 很想知道他站在原地能否看见 Yjq,帮助他解决这个问题。
【输入格式】
第一行两个数
第二行两个数
第三行四个数
第四行四个数
【输出格式】
如果 Hja 站在原地能看到 Yjq,则输出”YES”,否则输出”NO”。
【样例输入 1】
-1 31 30 2 0 40 0 0 1
【样例输出 1】
NO
【样例输入 2】
0 01 10 1 1 0-100 -100 -101 -101
【样例输出 2】
NO
【样例输入 3】
0 01 10 1 1 0-1 1 1 3
【样例输出 3】
YES
【样例输入 4】
0 010 0100 100 101 1011 0 3 0
【样例输出 4】
YES
【数据规模与约定】
对于
solution
hja只有在两种情况下可以看见yjq
不需要镜子就可以直接看见yjq
- 直接看视线被墙挡住,但可以通过镜子看见
所以就可以先判断能否直接看见,在判断可不可以通过镜子看见
不能通过镜子看见有三种情况
入射光线被墙挡住
- 反射光线被墙挡住
- 两个人不在镜子的同一侧
还有就是要注意题目中说的一些特殊情况
这种情况也可以看见
算是一道计算几何入门题目
code
#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const double eps=1e-8;int sgn(double x) { if(fabs(x)<eps) return 0; if(x>0.00) return 1; return -1;}struct Point { double x,y; Point(double x=0.00,double y=0.00): x(x),y(y) {} void SCANF() { scanf("%lf%lf",&x,&y); return; } Point operator + (const Point &q) const { return Point(x+q.x,y+q.y);; } Point operator - (const Point &q) const { return Point(x-q.x,y-q.y); } Point operator * (const double &q) const { return Point(x*q,y*q); }};Point hja,yjq,w1,w2,m1,m2;double cross(Point a,Point b) { return a.x*b.y-b.x*a.y;}double dot(Point a,Point b) { return a.x*b.x+a.y*b.y;}double cross(Point p1,Point p2,Point p3,Point p4) { if(sgn(cross(p2-p1,p3-p1))*sgn(cross(p2-p1,p4-p1))==1) return false; if(sgn(cross(p4-p3,p1-p3))*sgn(cross(p4-p3,p2-p3))==1) return false; if(sgn(max(p1.x,p2.x)-min(p3.x,p4.x))==-1) return false; if(sgn(max(p1.y,p2.y)-min(p3.y,p4.y))==-1) return false; if(sgn(max(p3.x,p4.x)-min(p1.x,p2.x))==-1) return false; if(sgn(max(p3.y,p4.y)-min(p1.y,p2.y))==-1) return false; return true;}Point GetCross(Point p1,Point p2,Point p3,Point p4) { double a=p2.y-p1.y; double b=p1.x-p2.x; double c=-p1.x*p2.y+p1.y*p2.x; double d=p4.y-p3.y; double e=p3.x-p4.x; double f=-p3.x*p4.y+p3.y*p4.x; double x=(b*f-c*e)/(a*e-b*d); double y=(a*f-c*d)/(b*d-a*e); return Point(x,y);}Point calc_foot(Point p1,Point p2,Point p3) { double ratio=dot(p1-p2,p3-p2)/dot(p3-p2,p3-p2); return p2+(p3-p2)*ratio;}bool Judge() { if(!cross(hja,yjq,w1,w2)) { if(!cross(hja,yjq,m1,m2)) return true; if(!sgn(cross(m1-hja,m2-hja))&&!sgn(cross(m1-yjq,m2-yjq))) return true; } if(sgn(cross(m2-m1,hja-m1))*sgn(cross(m2-m1,yjq-m1))==1) { Point foot=calc_foot(yjq,m1,m2); foot=foot*2.0-yjq; if(cross(hja,foot,m1,m2)) { foot=GetCross(hja,foot,m1,m2); if(!cross(hja,foot,w1,w2)&&!cross(foot,yjq,w1,w2)) return true; } } return false;}int main() { hja.SCANF(),yjq.SCANF(); w1.SCANF(),w2.SCANF(); m1.SCANF(),m2.SCANF(); puts(Judge()?"YES":"NO"); return 0;}
3.c(c.cpp/c/pas)
时间限制
1000ms
空间限制
256MB
【问题描述】
你是能看到第三题的 friends 呢。——aoao
众所周知,八数码问题是一个非常难的问题,但是 Yjq 非常有面子,他把这道题简化了一番。现在给了你一个3 × 3的方格图,你的目标是通过不断移动使得相邻颜色的块形成联通块。你每次的移动方式是选择一列或者一行进行置换滑动(这个解释起来比较麻烦,看下面的图就懂了)。所谓置换滑动,就是所有格子沿着给定的方向顺次移动,最后一个格子会被置换到最前面的过程。现在给定整个方格图,以及每个格子是否能够移动,求使得相同颜色联通的最小步数。
【输入格式】
输入为3 × 3的方格图,每个位置由五个字符组成,前四个字符分别表示上下
左右四个部分的颜色,第五个字符表示该格子是否能够移动,其中
不能移动。
【输出格式】
一行一个整数代表答案。
【样例输入】
GGGG0 GGGG0 GGGG0OGOO0 GGGG0 OGOO0OOOO0 OGGG1 OOOO0
【样例输出】
5
【样例解释】
【数据规模与约定】
对于
solution
- 因为每个格子都包含4个三角形,所以直接把一个格子看成4个点然后建图
- 然后就是爆搜,zhx:爆搜真的没什么好讲的.
code
200+行一点也不长呢
#include<queue>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct Edge { int u,v,next; Edge(int u=0,int v=0,int next=0): u(u),v(v),next(next) {}};Edge edge[110];int head[50],cnt;void addedge(int u,int v) { edge[++cnt]=Edge(u,v,head[u]); head[u]=cnt; edge[++cnt]=Edge(v,u,head[v]); head[v]=cnt; return;}struct rec { int s,step; rec(int s=0,int step=0): s(s),step(step) {}};int tmp[5][5],color[50];int Map[10][5];int nowmap[5][5],newmap[5][5];bool num[10],use[87654325];bool vis[50],col_find[5];bool col[5],row[5];char ch[10];queue<int> q;bool Judge(int now_s) { memset(num,false,sizeof(num)); for(int i=3;i>=1;i--) for(int j=3;j>=1;j--) if(i!=3||j!=3) { tmp[i][j]=now_s%10; num[now_s%10]=true; now_s/=10; } for(int i=0;i<9;i++) if(!num[i]) { tmp[3][3]=i; break; } int Count=0; for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) for(int k=1;k<=4;k++) color[++Count]=Map[tmp[i][j]][k]; memset(vis,false,sizeof(vis)); memset(col_find,false,sizeof(col_find)); for(int i=1;i<=36;i++) if(!vis[i]) { if(col_find[color[i]]) return false; col_find[color[i]]=true; for(;!q.empty();q.pop()); q.push(i); vis[i]=true; while(!q.empty()) { int u=q.front(); q.pop(); for(int j=head[u];j;j=edge[j].next) { int v=edge[j].v; if(color[v]==color[u]&&!vis[v]) { vis[v]=true; q.push(v); } } } } return true;}queue<rec> Q;int bfs(int now_s) { int step=0; rec now=rec(now_s,0); Q.push(now); use[now_s]=true; while(!Q.empty()) { now=Q.front(); Q.pop(); now_s=now.s; step=now.step; memset(num,false,sizeof(num)); for(int i=3;i>=1;i--) for(int j=3;j>=1;j--) if(i!=3||j!=3) { nowmap[i][j]=now_s%10; num[now_s%10]=true; now_s/=10; } for(int i=0;i<9;i++) if(!num[i]) { nowmap[3][3]=i; break; } int new_s,T; for(int i=1;i<=3;i++) { if(!row[i]) { for(int j=1;j<=3;j++) for(int k=1;k<=3;k++) newmap[j][k]=nowmap[j][k]; T=newmap[i][1]; newmap[i][1]=newmap[i][2]; newmap[i][2]=newmap[i][3]; newmap[i][3]=T; new_s=0; for(int j=1;j<=3;j++) for(int k=1;k<=3;k++) if(j!=3||k!=3) new_s=new_s*10+newmap[j][k]; if(!use[new_s]) { use[new_s]=true; if(Judge(new_s)) return step+1; Q.push(rec(new_s,step+1)); } T=newmap[i][1]; newmap[i][1]=newmap[i][2]; newmap[i][2]=newmap[i][3]; newmap[i][3]=T; new_s=0; for(int j=1;j<=3;j++) for(int k=1;k<=3;k++) if(j!=3||k!=3) new_s=new_s*10+newmap[j][k]; if(!use[new_s]) { use[new_s]=true; if(Judge(new_s)) return step+1; Q.push(rec(new_s,step+1)); } } if(!col[i]) { for(int j=1;j<=3;j++) for(int k=1;k<=3;k++) newmap[j][k]=nowmap[j][k]; T=newmap[1][i]; newmap[1][i]=newmap[2][i]; newmap[2][i]=newmap[3][i]; newmap[3][i]=T; new_s=0; for(int j=1;j<=3;j++) for(int k=1;k<=3;k++) if(j!=3||k!=3) new_s=new_s*10+newmap[j][k]; if(!use[new_s]) { use[new_s]=true; if(Judge(new_s)) return step+1; Q.push(rec(new_s,step+1)); } T=newmap[1][i]; newmap[1][i]=newmap[2][i]; newmap[2][i]=newmap[3][i]; newmap[3][i]=T; new_s=0; for(int j=1;j<=3;j++) for(int k=1;k<=3;k++) if(j!=3||k!=3) new_s=new_s*10+newmap[j][k]; if(!use[new_s]) { use[new_s]=true; if(Judge(new_s)) return step+1; Q.push(rec(new_s,step+1)); } } } } return 0;}#define id(i,j,k) ((i-1)*12+(j-1)*4+k)int main() { for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) { addedge(id(i,j,1),id(i,j,3)); addedge(id(i,j,1),id(i,j,4)); addedge(id(i,j,2),id(i,j,3)); addedge(id(i,j,2),id(i,j,4)); if(i!=3) addedge(id(i,j,2),id(i+1,j,1)); if(j!=3) addedge(id(i,j,4),id(i,j+1,3)); } int Count=0; for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) { scanf("%s",ch+1); for(int k=1;k<=4;k++) if(ch[k]=='R') Map[Count][k]=0; else if(ch[k]=='G') Map[Count][k]=1; else if(ch[k]=='B') Map[Count][k]=2; else Map[Count][k]=3; if(ch[5]=='1') row[i]=col[j]=true; Count++; } int now_s=1234567; if(Judge(now_s)) { puts("0\n"); return 0; } printf("%d\n",bfs(now_s)); return 0;}
- 10.1 test solution.
- 8.15 Test Problem Solution.
- 9.17 test solution.
- 9.18 test solution.
- 10.2 test solution.
- 10.3 test solution.
- 10.4 test solution.
- 10.5 test solution.
- 10.6 test solution.
- 10.7 test solution.
- 10.28 test solution.
- <<.net test automation Recipes a problem solution appoach
- 如何在solution中添加一个test case
- 如何在solution中添加一个test case
- Google Programming Test Problem SecretSum C++ 11 Solution
- Solution:
- solution
- test
- 单源最短路径问题-迪杰斯特拉(Dijkstra)算法
- Deep Learning for Chatbots, Part 2 – Implementing a Retrieval-Based Model in Tensorflow
- SpringMVC源码分析(一)之DispatcherServlet
- 欢迎使用CSDN-markdown编辑器
- 非常可乐 HDU1495
- 10.1 test solution.
- 2016-2017 ACM-ICPC, NEERC, Central Subregional Contest【9/11】
- SparkStreaming maxmind-GeoLite2 第三方对象序列化问题
- Learning Reinforcement Learning (with Code, Exercises and Solutions)
- 多表连接
- Scrapy学习笔记(1)
- BZOJ2118: 墨墨的等式 思维建图
- servlet的重定向(response.sendRedirect())
- 【机房收费系统】——任务启动