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);
}
View Code

 

 

 

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;
}
View Code

 

 

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);
         }
    }
}
View Code

 

以上是关于2017国庆 清北学堂 北京综合强化班 Day1的主要内容,如果未能解决你的问题,请参考以下文章

北京清北 综合强化班 Day1

清北学堂国庆day1解题报告

2017.10.3北京清北综合强化班DAY3

2017.10.5北京清北综合强化班DAY5

洛谷P1080 [NOIP2012提高组D1T2]国王游戏 [2017年5月计划 清北学堂51精英班Day1]

北京清北 综合强化班 Day5