首先我想说我可能又要开始更blog了...但不是在原来的平台...
自己忘性挺大的...有的时候凭着一点模糊的记忆...永远都没有办法将事情变得系统...
Acyclic_SD's First Training...
首先吐槽,这个队名真有那么难记吗...)
赛场上 solved 10 out of 13 赛后浩然帮改过了K 第二天我补掉了了J
A题 “首先你要看出它是棵树” 接着就是个LCA求dep的事情.当然这题不是我写的,想来建图的过程还是有一点点码农的...队友很劲...btw...记得自己以前专门喜欢离线求Lca...但现在也没什么大必要就是了
B题 是个几何...几何...圆环内的两个点最短路径...大胆猜想作两条切线...又是队友实现的...nbnb
C也是个签到题 有向无环图找任意两点间最长路径...应该是?...其实题目都应该好好读的...不论是跟榜的题还是没有人做的题...如果一场比赛下来连题目都没通读完的话...那确实可以怀疑一下自己的比赛状态了
D题 珍贵又稀有的我可以1A的题(雾以后要增加1A率)... 确认了一下以后就单开了...应该是个大签到题
E题 欧拉方法球素数+gcd然后就没了(这样想想这套题真的很良心 连数学题都是水水的) 队友wa到爆炸的原因是没有判断1是否为素数...我check的时候想到了这个问题来着...但是没有细读代码
F题 貌似是建模以后看出来是fibonacci number就好了 + Be careful about monsters with power 1
G题 哈哈哈哈哈啃了挺久的题解 但还是摸了 几何题 计算卫星与地球上某一点的距离 其中给出的条件不是很好转换 经度纬度...与赤道的夹角和交点...此时突然觉得heltion老师是无人能敌...
H题 依旧没看...原来队友切题的时候我都在纠结I题...应该是个比较暴力的数学...算出复杂度不会炸以后似乎就可以做了
I题 莫名其妙变成了没人看得懂的阅读理解题 然后wa到爆炸..搁浅了很久...当然这个题意确实写的很不怎么样
J题 拼图题 是个大模拟 想来应该贴一下代码 毕竟以后要一点点积累模拟的正确姿势...看着精妙的std确实可以使自己补题的效率迅速提高 x) 一开始数组开小了(因为每块拼图都有四个方向) 后来总算在qsc例会的时候改过了...需要注意的point: vector使用之前记得resize 否则至少在我本地会RE 然后多用queue 存两个位置的时候可以考虑xor嗯
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#define N 505050
#define ll long long
using namespace std;
int xmin=0,xmax=0,ymin=0,ymax=0;
int n,dx[10],dy[10],val[N*4],ch[10],b[N][5],x[N],y[N];
vector<vector<int> > res;
queue<int>q;bool mark[N];
void work(int *b){
for(int i=1;i<=4;i++)b[i-1]=b[i]; b[4]=b[0];
}
int main(){
// freopen("1.in","r",stdin);
dx[1]=1;dx[2]=0;dx[3]=-1;dx[4]=0;
dy[1]=0;dy[2]=1;dy[3]=0;dy[4]=-1;
ch[1]=3;ch[2]=4;ch[3]=1;ch[4]=2;
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=4;j++){
cin>>b[i][j];
val[b[i][j]]^=i;
}
}
q.push(1);
mark[1] = true;
while(!q.empty()){
int i=q.front();q.pop();
xmin=min(xmin,x[i]);
xmax=max(xmax,x[i]);
ymin=min(ymin,y[i]);
ymax=max(ymax,y[i]);
for(int k=1;k<=4;k++){
int e=b[i][k];
if(e==0)continue;
int j=val[e]^i;
if(mark[j])continue;
x[j]=x[i]+dx[k];
y[j]=y[i]+dy[k];
while(b[j][ch[k]]!=e)work(b[j]);
q.push(j);
mark[j]=true;
}
}
for(int i=1;i<=n;i++)if(!mark[i]){
printf("impossible\n");
return 0;
}
int h=xmax-xmin+1,w=ymax-ymin+1;
//printf("%d %d\n",h,w);
//return 0;
if((ll)h*(ll)w!=(ll)n){
printf("impossible\n");
return 0;
}
res.resize(h+10);
for(int i=1;i<=h;i++)res[i].resize(w+10);
for(int i=1;i<=n;i++)res[x[i]-xmin+1][y[i]-ymin+1]=i;
for(int x=1;x<=h;x++)
for(int y=1;y<=w;y++)
if(res[x][y]==0){
printf("impossible\n");
return 0;
}
for(int x=1;x<=h;x++)
for(int y=1;y<=w;y++)
for(int k=1;k<=4;k++){
int xx=x+dx[k],yy=y+dy[k];
if(xx<1 || yy<1 || xx>h || yy>w){
if(b[res[x][y]][k]!=0){
printf("impossible\n");
return 0;
}
}else{
if(b[res[x][y]][k]!=b[res[xx][yy]][ch[k]] || b[res[x][y]][k]==0){
printf("impossible\n");
return 0;
}
}
}
printf("%d %d\n",h,w);
for(int i=1;i<=h;i++){
for(int j=1;j<=w;j++)
printf("%d ",res[i][j]);
printf("\n");
}
return 0;
}
K题 01背包 将i个物品(正好)放入j的长度之中 使它们(j+10-g)/i最大 因为是i个而不是前i个 所以比原来多个一层循环
L题 类似于扫雷 幸好是想清楚以后写的 所以1A
M题 并查集启发式合并...而我居然写了最小生成树+LCA...下面std CODE (直接把询问扔进set orz)
#include <bits/stdc++.h>
using namespace std;
#define FORN(i,n) for (int i = 0; i < (n); i++)
const int N = 1010, Q = 1e5 + 10;
int h[N*N], p[N*N];
set<int> s[N*N];
int res[Q];
int Find(int a) {
if (a == p[a]) return a;
return p[a] = Find(p[a]);
}
void Union(int a, int b, int h) {
a = Find(a), b = Find(b);
if (a == b) return;
if (s[a].size() > s[b].size()) swap(a,b);
for (int i: s[a]) {
if (s[b].count(i)) {
res[i] = h;
s[b].erase(i);
} else {
s[b].insert(i);
}
}
p[a] = b;
}
int I(int x, int y) { return x*N + y; }
const int dx[] = {1,-1,0,0}, dy[] = {0,0,1,-1};
int main() {
int m, n, q;
cin >> m >> n >> q;
FORN(x,m) FORN(y,n) cin >> h[I(x,y)];
FORN(i,q) {
int x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
x1--, y1--, x2--, y2--;
s[I(x1,y1)].insert(i);
s[I(x2,y2)].insert(i);
if (x1 == x2 && y1 == y2) res[i] = h[I(x1,y1)];
}
vector<tuple<int,int,int>> v;
iota(p,p+(N*N),0);
FORN(x,m) FORN(y,n) v.emplace_back(h[I(x,y)],x,y);
sort(begin(v),end(v));
for (auto t: v) {
int hh, x, y;
tie(hh,x,y) = t;
FORN(k,4) {
int nx = x+dx[k], ny = y+dy[k];
if (nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
if (h[I(nx,ny)] > h[I(x,y)]) continue;
Union(I(x,y),I(nx,ny),hh);
}
}
FORN(i,q) cout << res[i] << endl;
}