前言
题目较水,恭喜 lcj
神仙 AK
本场比赛。
T1
稍微思索一番,不难推出公式为 $$ (max(w_1,w_2)+1) imes 2+(h_1+h_2+1) imes 2 $$ (变形很多,这里给出一种)。
Code
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
using namespace std;
#define ull unsigned ll
#define INF 0x3f3f3f3f
#define reg register
#define ll long long
#define GC getchar()
#define R read()
ll read(){
char c=GC; ll s=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-f;c=GC;}
while(c>='0'&&c<='9'){s=s*10+c-'0';c=GC;}
return s*f;
}
int main(){
int a(R), b(R), c(R), d(R);
printf("%d",(max(a,c)+1)*2+(b+d+1)*2);
return 0;
}
T2
二分+递归。
首先排序,然后不断从中间劈开,从最小的单位开始回溯,回溯时处理两点分别在两段的情况即可(注意优化)。
Code
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
using namespace std;
#define reint register int
#define ull unsigned ll
#define INF 0x3f3f3f3f
#define ll long long
#define GC getchar()
#define MAXN 200005
#define R read()
ll read(){
ll s=0,f=1;
char c=GC;
while(c<'0'||c>'9'){if(c=='-')f=-f;c=GC;}
while(c>='0'&&c<='9'){s=s*10+c-'0';c=GC;}
return s*f;
}
typedef double db;
struct node {
db x,y;
bool operator < (const node &Get) const {
if(y!=Get.y) return y<Get.y; return x<Get.x;
}
} p[MAXN];
struct nodeX {
db x,y; int i;
bool operator < (const nodeX &Get) const {
if(x!=Get.x) return x<Get.x; return y<Get.y;
}
} p1[MAXN];
int n;
db Len(db _,db _1,db _2,db _3) { return sqrt((_-_2)*(_-_2)+(_1-_3)*(_1-_3)); }
db dfs(int LfI,int RtI) {
if(LfI==RtI) return INF;
if(LfI==RtI-1) return Len(p[LfI].x,p[LfI].y,p[RtI].x,p[RtI].y);
int mid=(LfI+RtI)/2;
db ans=min(dfs(LfI,mid),dfs(mid+1,RtI));
int pn=0;
for(int i=LfI;i<=RtI;++i){
if(!(fabs(p[i].y-p[mid].y)>ans)){
p1[++pn].x=p[i].x;
p1[pn].y=p[i].y;
}
}
sort(p1+1,p1+pn+1);
for(int i=1;i<=pn;++i)
for(int j=i+1;j<=pn&&!(p1[j].x-p1[i].x>ans);++j)
ans=min(ans,Len(p1[i].x,p1[i].y,p1[j].x,p1[j].y));
return ans;
}
int main(){
cin>>n; for(int i=1;i<=n;++i) cin>>p[i].x>>p[i].y;
sort(p+1,p+n+1); return !printf("%.4lf",dfs(1,n));
}
T3
原题:P3916 图的遍历
不难发现,若 1
能够到 4
,则反向建边 4
一定可以到 1
。
稍加推理知,反向建边后遍历点 n
至 1
,看它们能到达哪里,能到达的地方若是之前没有被到达过则那个地方能到达的最大的点就是它。
Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
using namespace std;
#define R read()
#define GC getchar()
#define ll long long
#define ull unsigned long long
#define INF 0x7fffffff
#define LLINF 0x7fffffffffffffff
ll read(){
ll s=0,f=1;
char c=GC;
while(c<'0'||c>'9'){if(c=='-')f=-f;c=GC;}
while(c>='0'&&c<='9'){s=s*10+c-'0';c=GC;}
return s*f;
}
int n,m;
int u,v;
int ans[100010];
vector<int> e[100010];
void dfs(int now,int id){
if(ans[now]){
return ;
}
ans[now]=id;
for(int i=0;i<e[now].size();++i){
dfs(e[now][i],id);
}
}
int main(){
n=R;m=R;
for(int i=1;i<=m;++i){
u=R;v=R;
e[v].push_back(u);
}
for(int i=n;i>=1;--i){
dfs(i,i);
}
for(int i=1;i<=n;++i){
printf("%d ",ans[i]);
}
return 0;
}
T4
原题:P1363 幻象迷宫
裸暴力。
稍加思索排除几种不正确算法,最后选出正解(笑)。
若一个点能够被不重复的经过两次,则有解。
因为是由相同的阵法组成,所以若是经过了另一个阵法的能与初始阵法相对应的点,则称不重复的经过两次。
正确性待大家证明(笑)。
最后注意坐标问题,因为取模所以会出现 0
哦。
Code
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
using namespace std;
#define ull unsigned ll
#define INF 0x3f3f3f3f
#define reg register
#define ll long long
#define GC getchar()
#define R read()
ll read(){
char c=GC; ll s=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-f;c=GC;}
while(c>='0'&&c<='9'){s=s*10+c-'0';c=GC;}
return s*f;
}
int n,m,ax,ay; char mp[1505][1505];
int flag,vis[1505][1505][3];
int dx[7]={0,-1,1,0,0};
int dy[7]={0,0,0,-1,1};
void dfs(int x,int y,int modx,int mody){
if((vis[modx][mody][0]!=x||vis[modx][mody][1]!=y)&&vis[modx][mody][2])
{ flag=1; return ; }
if(vis[modx][mody][0]==x&&vis[modx][mody][1]==y&&vis[modx][mody][2])
return ;
vis[modx][mody][0]=x;
vis[modx][mody][1]=y;
vis[modx][mody][2]=1;
for(int i=1;i<=4;++i){
int tx=x+dx[i], ty=y+dy[i];
int modtx=(modx+dx[i]+n)%n, modty=(mody+dy[i]+m)%m;
if(mp[modtx][modty]!='#')
dfs(tx,ty,modtx,modty);
}
}
int main(){
while(cin>>n>>m){
memset(vis,0,sizeof(vis)); flag=0;
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
cin>>mp[i][j];
if(mp[i][j]=='S') ax=i, ay=j;
}
}
dfs(ax,ay,ax,ay);
if(flag) puts("Yes");
else puts("No");
}
return 0;
}