清北学堂国庆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解题报告的主要内容,如果未能解决你的问题,请参考以下文章