前言
实训中, 中午11点半放学, 下午2点上课, 12点的比赛…
11点提前溜了, 随便吃了点就赶回来了, 据说实验室停空调了, 正好在教室打比赛.
比赛开始我和yl一人A了一道签到, 然后我去看K, yl和jwr去看F, 我推了一个小时发现思路错了, 紧急呼叫yl回来看K. 然后他半个小时A了… 我去找其他题, 发现I是个搜索题, 心想上场比赛的搜索我wa了, 这场一定要一雪前耻! 然后又wa了… F题也是, 公式推出来了, 但最后相交的体积感觉求得有一些问题, 样例能过, 数据过不去. yl来改我的I题, 觉得是字典序的问题, 但应该不是. 最后3题罚坐.
赛后通过yym的指点, 发现自己I题犯了一个很蠢的问题, 具体题干里说
C. Draw Grids
题意
两人对n * m的区域分别进行连线, 不能有环, 走不了的人输
分析
求一个图的最小生成树边数, 对点的数量求奇偶即可
代码(队友的)
#include<bits/stdc++.h>
using namespace std;
int n,m;
int main()
{
cin>>n>>m;
if((n*m)&1) cout<<"NO";
else cout<<"YES";
return 0;
}
D. Er Ba Game
题意
两个人每人俩数字, 比大小
分析
模拟就完事了, 我写了一堆if else, 非常丑陋
代码
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int t;
int a1, b1, a2, b2;
int main(void)
{
cin >> t;
while (t --)
{
cin >> a1 >> b1 >> a2 >> b2;
if (a1 > b1) swap(a1, b1);
if (a2 > b2) swap(a2, b2);
if (a1 == 2 && b1 == 8)
{
if (a2 == 2 && b2 == 8) puts("tie");
else puts("first");
}
else
{
if (a2 == 2 && b2 == 8) puts("second");
else
{
if (a1 == b1)
{
if (a2 == b2)
{
if (a1 > a2) puts("first");
else if (a2 > a1) puts("second");
else puts("tie");
}
else puts("first");
}
else
{
if (a2 == b2) puts("second");
else
{
if ((a1 + b1) % 10 > (a2 + b2) % 10) puts("first");
else if ((a1 + b1) % 10 < (a2 + b2) % 10) puts("second");
else
{
if (b1 > b2) puts("first");
else if (b2 > b1) puts("second");
else puts("tie");
}
}
}
}
}
}
return 0;
}
F. Girlfriend
题意
根据两点之间的距离不小于k倍, 得到两个球, 求这两个球的公共体积
分析
比赛的时候才知道这东西叫阿尼波斯圆, 有一个公式专门求公共部分体积, 比赛的时候硬推的, 只推出了平面内成立的情况, 空间中还有很多情况没考虑到
代码
//后续补充
I. Penguins
题意
俩企鹅, 分别在两幅图里走, 走的上下方向相同, 左右方向相反, 撞墙了就不会往前走, 输出最后的路径
分析
很明显一道搜索题, 只是要同时对两幅图进行搜索, 一开始思路是开两个队列分别进行广搜, 但发现二者是同时进行的, 因此把思路转变为开一个四维的数组, 对每一个同时到达位置进行标记, 按照字典序进行输出即可
但是比赛的时候犯了一个很严重的失误, 最后在输出的时候, 我选择记录每个点是从哪个点走过来的. 这种方法在只有一幅图的时候显然是可行而且比较好的, 但是有两幅图, 左边的企鹅可能在某一步不动才是结果最优, 这样就不知道"不动"的这次方向是哪里了, 因此导致最终结果完全错误了
经过yym的指点, 代码简单加上一个方向的判断就过了
代码
#include<cstdio>
#include<queue>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 22;
typedef struct node{
int x1, y1, x2, y2;
}Node;
char g1[N][N], g2[N][N];
int n = 20;
int dx1[4] = {1, 0, 0, -1}, dy1[4] = {0, -1, 1, 0};
int dx2[4] = {1, 0, 0, -1}, dy2[4] = {0, 1, -1, 0};
bool st[N][N][N][N];
string s;
int ope[N][N][N][N];
Node pre[N][N][N][N];
Node bfs()
{
queue<node> q;
q.push({19, 19, 19, 0});
st[19][19][19][0] = true;
pre[19][19][19][0] = {-1, -1, -1, -1};
while (q.size())
{
Node temp = q.front();
q.pop();
int tx1 = temp.x1, tx2 = temp.x2, ty1 = temp.y1, ty2 = temp.y2;
if (tx1 == 0 && ty1 == 19 && tx2 == 0 && ty2 == 0) return {tx1, ty1, tx2, ty2};
for (int i = 0; i < 4; i ++)
{
bool flag1 = true, flag2 = true;
int nx1 = tx1 + dx1[i], ny1 = ty1 + dy1[i], nx2 = tx2 + dx2[i], ny2 = ty2 + dy2[i];
if (nx1 < 0 || ny1 >= n || ny1 < 0 || nx1 >= n || g1[nx1][ny1] == '#')
{
flag1 = false;
nx1 = tx1, ny1 = ty1;
}
if (nx2 < 0 || nx2 >= n || ny2 < 0 || ny2 >= n || g2[nx2][ny2] == '#')
{
flag2 = false;
nx2 = tx2, ny2 = ty2;
}
if (!flag1 && !flag2) continue;
if (st[nx1][ny1][nx2][ny2]) continue;
st[nx1][ny1][nx2][ny2] = true;
pre[nx1][ny1][nx2][ny2] = {tx1, ty1, tx2, ty2};
ope[nx1][ny1][nx2][ny2] = i;
q.push({nx1, ny1, nx2, ny2});
}
}
}
char dir(int x1, int y1, int x2, int y2)
{
if (x2 - x1 == 1) return 'D';
if (x2 - x1 == -1) return 'U';
if (y2 - y1 == 1) return 'R';
if (y2 - y1 == -1) return 'L';
}
int main(void)
{
for (int i = 0; i < n; i ++)
{
scanf("%s", g1[i]);
scanf("%s", g2[i]);
}
int cnt = 0;
Node t = bfs();
Node l = pre[t.x1][t.y1][t.x2][t.y2];
char op[]={'D','L','R','U'};
while (l.x1 != -1)
{
g1[t.x1][t.y1] = 'A';
g2[t.x2][t.y2] = 'A';
s += op[ope[t.x1][t.y1][t.x2][t.y2]];
t = l;
l = pre[t.x1][t.y1][t.x2][t.y2];
cnt ++;
}
g1[t.x1][t.y1] = 'A';
g2[t.x2][t.y2] = 'A';
printf("%d\n", cnt);
reverse(s.begin(), s.end());
cout << s << endl;
for (int i = 0; i < n; i ++)
{
printf("%s %s\n", g1[i], g2[i]);
}
return 0;
}
总结
比赛时候还是应该多想一些可能情况的样例, 来方便进行调试, 本来以为是字典序的问题, 也构造了一组卡掉字典序的样例, 后来发现没问题, 还是想的少了一些
K. Stack
题意
给出一个单调栈计算到每个位置的时候栈内有多少元素, 求出原序列
分析
题解是使用拓扑排序, 或链表模拟的方式, 和湘潭邀请赛中的那个stack问题有点类似, 比赛的时候我想的方法比较复杂, 最终没有推导出来
代码(队友的)
//后续补充
#include<bits/stdc++.h>
#define PB(x) push_back(x)
#define pop() pop_back()
using namespace std;
const int N=1e6+9;
int n,k;
int a[N],vis[N],c[N];
vector<int>mi,ma;
struct node
{
int p,x;
bool operator < (const node &y) const
{
return p<y.p;
}
}b[N];
int main()
{
cin>>n>>k;
for(int i=1;i<=k;i++)
cin>>b[i].p>>b[i].x;
sort(b+1,b+1+k);
memset(c,-1,sizeof(c));
for(int i=1;i<=k;i++)
{
c[b[i].p]=b[i].p-b[i].x;
if(c[b[i].p]<0)
{
cout<<-1;
return 0;
}
}
c[0]=0;
for(int i=1;i<=n;i++)
{
if(c[i]==-1) c[i]=c[i-1];
if(c[i]<c[i-1])
{
cout<<-1;
return 0;
}
}
a[n]=n-c[n];
mi.PB(a[n]-1);
ma.PB(a[n]+1);
vis[a[n]]=1;
for(int i=n-1;i>=1;i--)
{
while(mi.size()&&(vis[mi.back()]||mi.back()<1||mi.back()>n)) mi.pop();
while(ma.size()&&(vis[ma.back()]||ma.back()<1||ma.back()>n)) ma.pop();
if(c[i]==c[i+1])
{
if(mi.empty())
{
cout<<-1;
return 0;
}
a[i]=mi.back();
mi.pop();
mi.PB(a[i]-1);
}
else
{
if(ma.empty())
{
cout<<-1;
return 0;
}
a[i]=ma.back()+c[i+1]-c[i]-1;
ma.pop();
ma.PB(a[i]+1);
mi.PB(a[i]-1);
}
vis[a[i]]=1;
}
for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
return 0;
}