2017国庆 清北学堂 北京综合强化班 Day1
Posted 日拱一卒 功不唐捐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2017国庆 清北学堂 北京综合强化班 Day1相关的知识,希望对你有一定的参考价值。
期望得分:60+ +0=60+
实际得分:30+56+0=86
时间规划极端不合理,T2忘了叉积计算,用解析几何算,还有的情况很难处理,浪费太多时间,最后gg
导致T3只剩50分钟,20分钟写完代码,没调出来
设sum[i][j] 表示字母j出现次数的前缀和
那么题目要求我们 最大化sum[r][x]-sum[l-1][x]-(sum[r][y]-sum[l-1][y])
如果枚举r,再枚举y,时间复杂度为O(n*26),是可以承受的
但此时还有l-1未知,能否O(1)找到l-1呢?
我们发现式子可以化为 :sum[r][x]-sum[r][y]-(sum[l-1][x]-sum[l-1][y])
这样减号两边形式相同
那就可以用前缀和来维护
所以设mi[i][j] 表示 当前 sum[i]-sum[j] 的最小值
在枚举r之前,l肯定已经计算过,所以sum的第一维可以不再mi中体现
那么ans=max(sum[r][x]-sum[r][y]-mi[x][y],sum[r][y]-sum[l][x]-mi[y][x])
小细节:
zhx的std中,
另外记录了当前每个字符的上一个出现的位置last[i],更新mi[i][j]的位置pos[i][j]
在更新答案的时候,是sum[r][x]-sum[r][y]-mi[x][y]-(pos[x][y]==last[i])
原因是因为 题目中要求 用来计算答案的 字母必须在所选区间出现过
std 每次在用sum更新mi时,不能保证用的这个字符出现过
还不明白的话 ,把std 的那句判等去掉,跑一遍数据:hhfffff
所以 我们仅需要在更新mi的时候,判断sum[]是否为真
便可以把这个特殊判断和last,pos 数组 去掉
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 1000001 int sum[N],mi[26][26]; char s[N]; int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int n; scanf("%d",&n); scanf("%s",s+1); int ans=0; memset(mi,63,sizeof(63)); for(int i=1;i<=n;i++) { int now=s[i]-\'a\'; sum[now]++; for(int j=0;j<26;j++) if(sum[j]) ans=max(ans,max(sum[now]-sum[j]-mi[now][j],sum[j]-sum[now]-mi[j][now])); for(int j=0;j<26;j++) { if(sum[j] && sum[j]-sum[now]<mi[j][now]) mi[j][now]=sum[j]-sum[now]; if(sum[j] && sum[now]-sum[j]<mi[now][j]) mi[now][j]=sum[now]-sum[j]; } } printf("%d",ans); }
gg了。。。。。。
反射那块是怎么求的?
最后的交点怎么求的?
#include<cmath> #include<cstdio> #include<iostream> #include<algorithm> using namespace std; const double eps=1e-8; struct Point { double x,y; Point() { }; Point(double a,double b) { x=a; y=b; } void init() { scanf("%lf%lf",&x,&y); } }v,p,w1,w2,m1,m2; Point operator + (Point A,Point B) { return Point(A.x+B.x,A.y+B.y); } Point operator - (Point A,Point B) { return Point(A.x-B.x,A.y-B.y); } Point operator * (Point A,double a) { return Point(A.x*a,A.y*a); } int dcmp(double a) { if(fabs(a)<eps) return 0; return a>0 ? 1 : -1; } double Cross(Point A,Point B) { return A.x*B.y-A.y*B.x; } double Dot(Point A,Point B) { return A.x*B.x+A.y*B.y; } bool cross(Point P1,Point P2,Point P3,Point P4) { if(dcmp(Cross(P2-P1,P3-P1))*dcmp(Cross(P2-P1,P4-P1))==1) return false; if(dcmp(Cross(P4-P3,P1-P3))*dcmp(Cross(P4-P3,P2-P3))==1) return false; if(dcmp(fmax(P1.x,P2.x)-fmin(P3.x,P4.x))==-1) return false; if(dcmp(fmax(P1.y,P2.y)-fmin(P3.y,P4.y))==-1) return false; if(dcmp(fmax(P3.x,P4.x)-fmin(P1.x,P2.x))==-1) return false; if(dcmp(fmax(P3.y,P4.y)-fmin(P1.y,P2.y))==-1) return false; return true; } Point GetLineProjection(Point P,Point A,Point B) { Point v=B-A; return A+v*(Dot(v,P-A)/Dot(v,v)); } 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); } bool check() { if(!cross(v,p,w1,w2)) { if(!cross(v,p,m1,m2)) return true; if(dcmp(Cross(m1-v,m2-v))==0 && dcmp(Cross(m1-p,m2-p))==0) return true; } if(dcmp(Cross(m2-m1,v-m1))*dcmp(Cross(m2-m1,p-m1))==1) { Point foot=GetLineProjection(p,m1,m2); foot=foot*2.0-p; if(cross(v,foot,m1,m2)) { foot=getcross(v,foot,m1,m2); if(!cross(v,foot,w1,w2) && !cross(p,foot,w1,w2)) return true; } return false; } return false; } int main() { freopen("b.in","r",stdin); freopen("b.out","w",stdout); v.init(); p.init(); w1.init(); w2.init(); m1.init(); m2.init(); if(check()) puts("YES"); else printf("NO"); return 0; }
bfs,结构体内char数组3*3*6表示状态,map判重
#include<map> #include<queue> #include<cstring> #include<cstdio> #include<iostream> using namespace std; struct node { char s[3][3][6]; }cur,nxt; queue<node>q; map<string,int>mp; string t; int sum[4],cnt; bool v[3][3][4]; bool vis() { t.clear(); for(int i=0;i<3;i++) for(int j=0;j<3;j++) t+=nxt.s[i][j]; return mp.count(t); } void dfs(int i,int j,int k,char c) { cnt++; v[i][j][k]=true; if(!k) { if(nxt.s[i][j][2]==c && !v[i][j][2]) dfs(i,j,2,c); if(nxt.s[i][j][3]==c && !v[i][j][3]) dfs(i,j,3,c); if(i && nxt.s[i-1][j][1]==c && !v[i-1][j][1]) dfs(i-1,j,1,c); } else if(k==1) { if(nxt.s[i][j][2]==c && !v[i][j][2]) dfs(i,j,2,c); if(nxt.s[i][j][3]==c && !v[i][j][3]) dfs(i,j,3,c); if(i!=2 && nxt.s[i+1][j][0]==c && !v[i+1][j][0]) dfs(i+1,j,0,c); } else if(k==2) { if(nxt.s[i][j][0]==c && !v[i][j][0]) dfs(i,j,0,c); if(nxt.s[i][j][1]==c && !v[i][j][1]) dfs(i,j,1,c); if(j!=0 && nxt.s[i][j-1][3]==c && !v[i][j-1][3]) dfs(i,j-1,3,c); } else { if(nxt.s[i][j][0]==c && !v[i][j][0]) dfs(i,j,0,c); if(nxt.s[i][j][1]==c && !v[i][j][1]) dfs(i,j,1,c); if(j!=2 && nxt.s[i][j+1][2]==c && !v[i][j+1][2]) dfs(i,j+1,2,c); } } bool judge() { memset(v,false,sizeof(v)); bool ok=false; for(int i=0;i<3 && !ok;i++) for(int j=0;j<3 && !ok;j++) for(int k=0;k<4 && !ok;k++) if(nxt.s[i][j][k]==\'R\') { cnt=0; dfs(i,j,k,\'R\'); if(cnt!=sum[0]) return false; ok=true; } ok=false; for(int i=0;i<3 && !ok;i++) for(int j=0;j<3 && !ok;j++) for(int k=0;k<4 && !ok;k++) if(nxt.s[i][j][k]==\'G\') { cnt=0; dfs(i,j,k,\'G\'); if(cnt!=sum[1]) return false; ok=true; } ok=false; for(int i=0;i<3 && !ok;i++) for(int j=0;j<3 && !ok;j++) for(int k=0;k<4 && !ok;k++) if(nxt.s[i][j][k]==\'B\') { cnt=0; dfs(i,j,k,\'B\'); if(cnt!=sum[2]) return false; ok=true; } ok=false; for(int i=0;i<3 && !ok;i++) for(int j=0;j<3 && !ok;j++) for(int k=0;k<4 && !ok;k++) if(nxt.s[i][j][k]==\'O\') { cnt=0; dfs(i,j,k,\'O\'); if(cnt!=sum[3]) return false; ok=true; } return true; } int main() { freopen("c.in","r",stdin); freopen("c.out","w",stdout); for(int i=0;i<3;i++) for(int j=0;j<3;j++) { scanf("%s",cur.s[i][j]); for(int k=0;k<5;k++) t+=cur.s[i][j][k]; for(int k=0;k<4;k++) switch(cur.s[i][j][k]) { case \'R\':sum[0]++; break; case \'G\':sum[1]++; break; case \'B\':sum[2]++; break; case \'O\':sum[3]++; break; } } q.push(cur); mp[t]=1; bool ok; string a,b; while(!q.empty()) { cur=q.front(); q.pop(); a.clear(); for(int i=0;i<3;i++) for(int j=0;j<3;j++) a+=cur.s[i][j]; // left for(int i=0;i<3;i++) { ok=true; for(int j=0;j<3 && ok;j++) if(cur.s[i][j][4]==\'1\') ok=false; if(!ok) continue; nxt=cur; swap(nxt.s[i][0],nxt.s[i][1]); swap(nxt.s[i][1],nxt.s[i][2]); if(vis()) continue; if(judge()) { printf("%d",mp[a]); return 0; } b.clear(); for(int i=0;i<3;i++) for(int j=0;j<3;j++) b+=nxt.s[i][j]; mp[b]=mp[a]+1; q.push(nxt); } // right for(int i=0;i<3;i++) { ok=true; for(int j=0;j<3 && ok;j++) if(cur.s[i][j][4]==\'1\') ok=false; if(!ok) continue; nxt=cur; swap(nxt.s[i][2],nxt.s[i][1]); swap(nxt.s[i][1],nxt.s[i][0]); if(vis()) continue; if(judge()) { printf("%d",mp[a]); return 0; } b.clear(); for(int i=0;i<3;i++) for(int j=0;j<3;j++) b+=nxt.s[i][j]; mp[b]=mp[a]+1; q.push(nxt); } // up for(int j=0;j<3;j++) { ok=true; for(int i=0;i<3 && ok;i++) if(cur.s[i][j][4]==\'1\') ok=false; if(!ok) continue; nxt=cur; swap(nxt.s[0][j],nxt.s[1][j]); swap(nxt.s[1][j],nxt.s[2][j]); if(vis()) continue; if(judge()) { printf("%d",mp[a]); return 0; } b.clear(); for(int i=0;i<3;i++) for(int j=0;j<3;j++) b+=nxt.s[i][j]; mp[b]=mp[a]+1; q.push(nxt); } // down for(int j=0;j<3;j++) { ok=true; for(int i=0;i<3 && ok;i++) if(cur.s[i][j][4]==\'1\') ok=false; if(!ok) continue; nxt=cur; swap(nxt.s[2][j],nxt.s[1][j]); swap(nxt.s[1][j],nxt.s[0][j]); if(vis()) continue; if(judge()) { printf("%d",mp[a]); return 0; } b.clear(); for(int i=0;i<3;i++) for(int j=0;j<3;j++) b+=nxt.s[i][j]; mp[b]=mp[a]+1; q.push(nxt); } } }
以上是关于2017国庆 清北学堂 北京综合强化班 Day1的主要内容,如果未能解决你的问题,请参考以下文章