清北学堂国庆day1解题报告

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了清北学堂国庆day1解题报告相关的知识,希望对你有一定的参考价值。

解题报告

张炳琪

时间安排::

T1:十分钟打出暴力,想写正解耽误了30分钟。

T2:花了一个小时推了几个结论

T3:剩余时间一直在写,思路也是正确的搜索方向也是正确的,就是因为代码太长250多行写不完。

答题情况和错误分析::

T1:前不久跟一区的学了个n^2的区间算法,用上了得了60分,大数据又写了个贪心,得了10分

T2:关键是知识点没学过,如何判两条线段是否相交,我打出框架来就差这个函数不会写,然后乱写,盼不出来的输出YES 结果的分和全输出No的差不多。。

T3:这个题会做,想了个很好的方法来存图,时间不够不够不够啊,刚写完就交了,样例都没跑过,结果报零,250+代码。

题目解析:

T1:

满分做法挺耗脑的,遍历一遍记录前缀和,同时记录反向的最大值,然后用总区间减去前缀寻找最大值,注意当

 

T2:

做法流程如下

1:链接两人成线段,判断该线段是否和镜子相交,相交的话输出NO

2:判断是否和墙相交,不相交的话输出YES

3:分别做两点关于镜子的对称点,于原点交叉连线,判断连线是否和墙交叉

 

求两线段交叉方法,求出两个线段所在直线交点,判断是否存在于线段上

 

T3:

用9*9的矩阵表示方格,即可做到判断联通,之后就是判重检验转移的bfs,就是有些难写

代码::

T1:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>

using namespace std;

const int maxn=1000010;

int n,ans,p[26][26];
int note[26][26];// c bi b duochuxian de ci shu
int sum[26];
int last[26];
int nt[1234];
char s[maxn];
int judge()
{
    int minn = 9999999,maxx = -1;
    for(int i = a;i <= z;i++)
    {
        if(!nt[i])continue;
        minn = min(minn,nt[i]);
        maxx = max(maxx,nt[i]);
    }
    return maxx - minn;
}

int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);

    scanf("%d",&n);
    scanf("%s",s+1);
    if(n <= 1000)
    {
        for(int i = 1;i <= n;i++)
        {
            memset(nt,0,sizeof(nt));
            for(int j = i;j <= n;j++)
            {
                nt[s[j]]++;
                ans = max(ans,judge());
            }
        }
        printf("%d",ans);
        return 0;
    }
    for(int i = 1;i <= n;i++)
    {
        int op = s[i] - a;
        sum[op]++;
        last[op] = i;
        for(int j = 0;j < 26;j++)
        {
            if(op == j || !sum[j])continue;
            ans = max(ans,sum[j] - sum[op] + note[op][j] -(last[j] == p[op][j]));
            ans = max(ans,sum[op] - sum[j] + note[j][op] -(last[j] == p[j][op]));
        }
        for(int j = 0;j < 26;j++)
        {
            if(note[op][j] < sum[op] - sum[j])note[op][j] = sum[op] - sum[j],p[op][j] = op;
            if(note[j][op] < sum[j] - sum[op])note[j][op] = sum[j] - sum[op],p[j][op] = op;
        }
    }
    printf("%d\n",ans);
    return 0;
}

 

T2:

#include<cstdio>
#include<cmath>
using namespace std;

struct point{
    double x;
    double y;
}H,Y;

struct Edge
{
    point a;
    point b;
}wall_,mirror_;

double max(double a,double b)
{
    return a > b ? a : b;
}

double min(double a,double b)
{
    return a < b ? a : b;
}

bool judge(Edge op)
{
    int ax = max(H.x,Y.x);
    int bx = min(op.a.x,op.b.x);
    if(bx > ax)return false;
    ax = max(op.a.x,op.b.x);
    bx = min(H.x,Y.x);
    if(bx > ax)return false;
    
    int ay = max(H.y,Y.y);
    int by = min(op.a.y,op.b.y);
    if(by > ay)return false;
    ay = max(op.a.y,op.b.y);
    by = min(H.y,Y.y);
    if(by > ay)return false;
    return true;
}

int main()
{
    freopen("b.in","r",stdin);freopen("b.out","w",stdout);
    scanf("%lf%lf",&H.x,&H.y);
    scanf("%lf%lf",&Y.x,&Y.y);
    scanf("%lf%lf%lf%lf",&wall_.a.x,&wall_.a.y,&wall_.b.x,&wall_.b.y);
    scanf("%lf%lf%lf%lf",&mirror_.a.x,&mirror_.a.y,&mirror_.b.x,&mirror_.b.y);
    
    if(!judge(wall_) &&!judge(mirror_))
    {
        printf("YES");
        return 0;
    }
    if(!judge(mirror_))
    {
        printf("NO");
        return 0;
    }
    printf("NO");
    fclose(stdin);fclose(stdout);
    return 0;
}
/*
-1 3
1 3
0 2 2 4
0 0 0 1
NO

0 0
1 1
0 1 1 0
-1 1 1 3
YES

0 0
1 1
0 1 1 0
-100 -100 -101 -101
NO

0 0
10 0
100 100 101 101
1 0 3 0
YES

 

 

 

 

*/

更正

#include<cstdio>
#include<cmath>
#include<iostream> 
#define INF 23333333
#define eps 1e-9
using namespace std;

struct point{
    double x;
    double y;
    point(){
        x = 0;
        y = 0;
    }
};

struct Edge
{
    point a;
    point b;
    double k;//斜率 
    double b_;//截距 
    Edge(){
        k = 0;
        b_ = 0;
    }
}wall_,mirror_,peo,aa,bb;

double max(double a,double b)
{
    return a > b ? a : b;
}

double min(double a,double b)
{
    return a < b ? a : b;
}

void jisuan(Edge &a)
{
    if(a.a.x == a.b.x){
        a.k = INF;
        a.b_ = 0;
    }
    else
    {
        a.k = (a.b.y - a.a.y)/(a.b.x - a.a.x);
        a.b_ = a.a.y - a.k * a.a.x;
    }
}

point jiao(Edge a,Edge b)// 求交点
{
    point zz;
    if(a.k == INF || b.k == INF)
    {
        if(b.k == INF)swap(a,b);
        zz.x = a.a.x;
        zz.y = a.a.x * b.k + b.b_;
        return zz;
    }
    zz.x = (b.b_ - a.b_) / (a.k - b.k);
    zz.y = a.k * zz.x + a.b_;
    return zz;
} 

bool judge(Edge a,Edge b)// 用来判断两线段是否相交 
{
    point op = jiao(a,b);
    double X1 = a.a.x,X2 = a.b.x;
    if(X1 > X2)swap(X1,X2);
    if(op.x < X1 + eps || op.x > X2 - eps)return false;
    return true;
}

void trun()// 模拟入射光线反射光线 
{
    Edge op; 
    aa.a.x = op.a.x = peo.a.x;
    aa.a.y = op.a.y = peo.a.y;
    op.k = (-1) / mirror_.k;
    op.b_ = aa.a.y - aa.a.x * op.k;
    op.b.x = 2 * (mirror_.b_ - op.b_) / (op.k - mirror_.k) - op.a.x;
    op.b.y = op.b.x * op.k + op.b_;
    point zz = jiao(op,mirror_);
    aa.b.x = zz.x;
    aa.b.y = zz.y;
    
    bb.a.x = peo.b.x;bb.a.y = peo.b.y;
    bb.b.x = zz.x;bb.b.y = zz.y; 
}

void Init()
{
    scanf("%lf%lf",&peo.a.x,&peo.a.y);scanf("%lf%lf",&peo.b.x,&peo.b.y);
    scanf("%lf%lf%lf%lf",&wall_.a.x,&wall_.a.y,&wall_.b.x,&wall_.b.y);
    scanf("%lf%lf%lf%lf",&mirror_.a.x,&mirror_.a.y,&mirror_.b.x,&mirror_.b.y);
}

int main()
{
    freopen("b.in","r",stdin);freopen("b.out","w",stdout);
    Init();
    
    jisuan(wall_);jisuan(mirror_);jisuan(peo);
    if(judge(mirror_,peo)){cout << "NO";return 0;}
    if(!judge(wall_,peo)){cout << "YES";return 0;}
    trun();
    jisuan(aa);jisuan(bb);
    if(judge(wall_,aa) || judge(wall_,bb)){cout << "NO";return 0;}
    cout << "YES";
    return 0;
}

 

 

T3:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
char s[12];const int mod = 123456;const int rmod = 654321;bool visited[130000];bool rvisited[666666];bool xcan[3];bool ycan[3];int kuai[5];
struct Note{
    int op[9][9];
    int shu[3][3];
    int step;
    Note(){
        memset(op,0,sizeof(op));
        memset(shu,0,sizeof(shu));
    }
}be; 
int initx[4] = {-1,1,0,0};int inity[4] = {0,0,-1,1};
bool vis[9][9];int de[5];
int qiushu(Note ax){
    int ans = 100000000 * ax.shu[0][0] + 10000000 * ax.shu[0][1] +1000000 *ax.shu[0][2]+100000 *ax.shu[1][0] +10000 *ax.shu[1][1]  +1000 *ax.shu[1][2]+100 *ax.shu[2][0] + 10 * ax.shu[2][1]+ ax.shu[2][2];
}
void dfs(int x,int y,int wei,Note pig)
{
    vis[x][y] = true;
    de[pig.op[x][y]]++;
    for(int i = -1;i <= 1;i++)
        for(int j = -1;j <= 1;j++)
        {
            if(i == 0 && j == 0)continue;
            int nx = x + i;
            int ny = y + j;
            if(nx >= 0 && nx < 9 && ny >= 0 && ny < 9 && pig.op[nx][ny] == wei && !vis[nx][ny])
                dfs(nx,ny,wei,pig);
        }
}
bool judge(Note pig)
{
    memset(vis,0,sizeof(vis));
    memset(de,0,sizeof(de));
    for(int i = 0;i <= 8;i++)
        for(int j = 0;j <= 8;j++)
        {
            if(kuai[pig.op[i][j]] && !vis[i][j])
            {
                dfs(i,j,pig.op[i][j],pig);
                if(de[pig.op[i][j]] != kuai[pig.op[i][j]])
                    return false;
            }
        }
    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",s);// R 1   --   G 2   --  B 3 --  O 4 --
            for(int z = 0;z <= 3;z++)
            {
                if(s[z] == R)s[z] = 1;
                if(s[z] == G)s[z] = 2;
                if(s[z] == B)s[z] = 3;
                if(s[z] == O)s[z] = 4;
                kuai[s[z] - 0]++;
            }
            int xnow = i * 3 + 1;int ynow = j * 3 + 1;
            for(int tp = 0;tp < 4;tp++)
            {
                be.op[xnow + initx[tp]][ynow + inity[tp]] = s[tp] - 0;
            }
            if(s[4] == 1){
                xcan[i] = true;
                ycan[j] = true;
            }
        }
    for(int jkl = 0;jkl < 3;jkl++)
        for(int lll = 0;lll < 3;lll++)
    {
            be.shu[jkl][lll] = jkl * 3 + lll; 
    }
    int be_num = qiushu(be);
    visited[be_num % mod] = true;rvisited[be_num % rmod] = true;
    queue<Note>q;q.push(be);
    while(!q.empty())
    {
        Note zz = q.front();
        q.pop();
        if(judge(zz))
        {
            printf("%d",zz.step);return 0;
        }    
        for(int i = 0;i < 3;i++)
        {
            Note nx;
            nx = zz;
            nx.step = zz.step + 1;
            if(!xcan[i])
            {
                int xx= i * 3 + 1;
            
                for(int j = 0;j <= 8;j++)
                {
                    nx.op[xx - 1][(j + 3) % 9] = zz.op[xx - 1][j];
                    nx.op[xx][(j + 3) % 9] = zz.op[xx][j];
                    nx.op[xx + 1][(j + 3) % 9] = zz.op[xx + 1][j];
                    if(j < 3)nx.shu[i][(j + 1) % 3] = zz.shu[i][j]; 
                }
                int as = qiushu(nx);
                if(!visited[as % mod] && ! rvisited[as % rmod])
                {
                    visited[as % mod] = true;rvisited[as % rmod] = true;
                    q.push(nx);
                }
                nx = zz;
                nx.step = zz.step + 1;
                for(int j = 0;j <= 8;j++)
                {
                    nx.op[xx - 1][(j + 6) % 9] = zz.op[xx - 1][j];
                    nx.op[xx][(j + 6) % 9] = zz.op[xx][j];
                    nx.op[xx + 1][(j + 6) % 9] = zz.op[xx + 1][j];
                    if(j < 3)nx.shu[i][(j + 2) % 3] = zz.shu[i][j]; 
                }
                as = qiushu(nx);
                if(!visited[as % mod] && ! rvisited[as % rmod])
                {
                    visited[as % mod] = true;
                    rvisited[as % rmod] = true;
                    q.push(nx);
                }
            }
            if(!ycan[i])
            {
                int xx= i * 3 + 1;
                nx = zz;
                nx.step = zz.step + 1;
                for(int j = 0;j <= 8;j++)
                {
                    nx.op[(j + 3) % 9][xx - 1] = zz.op[j][xx - 1];
                    nx.op[(j + 3) % 9][xx] = zz.op[j][xx];
                    nx.op[(j + 3) % 9][xx + 1] = zz.op[j][xx + 1];
                    if(j < 3)
                    nx.shu[(j + 1) % 3][i] = zz.shu[j][i]; 
                }
                int as = qiushu(nx);
                if(!visited[as % mod] && ! rvisited[as % rmod])
                {
                    visited[as % mod] = true;
                    rvisited[as % rmod] = true;
                    q.push(nx);
                }
                nx = zz;
                nx.step = zz.step + 1;
                for(int j = 0;j <= 8;j++)
                {
                    nx.op[(j + 6) % 9][xx - 1] = zz.op[j][xx - 1];
                    nx.op[(j + 6) % 9][xx] = zz.op[j][xx];
                    nx.op[(j + 6) % 9][xx + 1] = zz.op[j][xx + 1];
                    if(j < 3)
                    nx.shu[(j + 2) % 3][i] = zz.shu[j][i]; 
                }
                as = qiushu(nx);
                if(!visited[as % mod] && ! rvisited[as % rmod])
                {
                    visited[as % mod] = true;
                    rvisited[as % rmod] = true;
                    q.push(nx);
                }
            }
        }
    }
    return 0;
}

 

以上是关于清北学堂国庆day1解题报告的主要内容,如果未能解决你的问题,请参考以下文章

清北学堂国庆day6解题报告

清北学堂国庆day7解题报告

清北学堂国庆day5解题报告

清北学堂国庆day3解题报告

清北学堂国庆day4解题报告

2017国庆 清北学堂 北京综合强化班 Day1