20190921
A1 100pts
暴力kmp
#include<bits/stdc++.h>
#define R register int
using namespace std;
namespace Luitaryi {
const int N=100010;
char s[N*3],s1[N],s2[N];
int l,l1,l2,nxt1[N],nxt2[N];
vector <int> p1,p2;
inline void main() {
scanf("%s",s+1); R p=1,q,tmpl=strlen(s+1);
while(s[p]!=',') ++p; q=p+1;
while(s[q]!=',') ++q;
memcpy(s1+1,s+p+1,sizeof(char)*(q-p-1));
memcpy(s2+1,s+q+1,sizeof(char)*(tmpl-q));
l1=q-p-1,l2=tmpl-q,l=p-1;
for(R i=2,j=0;i<=l1;i++) {
while(j&&s1[i]!=s1[j+1]) j=nxt1[j];
if(s1[j+1]==s1[i]) ++j; nxt1[i]=j;
}
for(R i=2,j=0;i<=l2;i++) {
while(j&&s2[i]!=s2[j+1]) j=nxt2[j];
if(s2[j+1]==s2[i]) ++j; nxt2[i]=j;
}
for(R i=1,j=0;i<=l;i++) {
while(j&&s[i]!=s1[j+1]) j=nxt1[j];
if(s[i]==s1[j+1]) ++j;
if(j==l1) p1.push_back(i),j=nxt1[j];
}
for(R i=1,j=0;i<=l;i++) {
while(j&&s[i]!=s2[j+1]) j=nxt2[j];
if(s[i]==s2[j+1]) ++j;
if(j==l2) p2.push_back(i-l2+1),j=nxt2[j];
}
if(!p1.size()||!p2.size()) puts("-1");
else if(p1[0]>=p2[p2.size()-1]) puts("-1");
else printf("%d\n",p2[p2.size()-1]-p1[0]-1);
}
} signed main() {Luitaryi::main(); return 0;}
A2 没卡精度+写挂 10pts
考试时直接用 set<pair<long double,long double> > 判重(也是没谁了)
当时特别想切掉这道题,于是想了各种情况(就是以为精度不会挂)
然后获得了10pts的好成绩。
后来问了问大家
woc为什么想这么少都能90pts
(原来大家都在卡精度)
下午听说有人改对了听了听他的思路
哈哈我能hack你(我xx考试时还能白想那么多?)
瞬间hack掉std。
原因是都没有把在圆上的点扔掉。
下面是改了的std
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef double db;
const int N = 1000, oo = (int)2e9;
const db eps = 1e-7;
struct vec {
db x, y;
}cs[N + 10];
vec operator + (const vec &a, const vec &b) { return (vec){a.x + b.x, a.y + b.y}; }
vec operator - (const vec &a, const vec &b) { return (vec){a.x - b.x, a.y - b.y}; }
vec operator * (const db &a, const vec &b) { return (vec){a * b.x, a * b.y}; }
db operator * (const vec &a, const vec &b) { return a.x * b.y - a.y * b.x; }
bool Eq(const db &a, const db &b) { return fabs(a - b) < eps; }
bool cmp(const vec &a, const vec &b) { return a.x < b.x || (Eq(a.x, b.x) && a.y < b.y); }
bool operator != (const vec &a, const vec &b) { return !Eq(a.x, b.x) || !Eq(a.y, b.y); }
db Dist(const vec &a) { return sqrt(a.x * a.x + a.y * a.y); }
struct line {
vec p, t;
}a[N + 10];
int n, m, r, cnt;
int l1, r1, l2, r2;
vec Cross(line a, line b) {
vec dt = b.p - a.p;
if (Eq(a.t * b.t, 0)) return (vec){oo, oo};
db t = (dt * b.t) / (a.t * b.t);
return a.p + (t * a.t);
}
int main() {
scanf("%d\n%d\n", &r, &n);
int ans = 1;
for (int i = 1; i <= n; ++i) {
scanf("%d%d%d%d\n", &l1, &r1, &l2, &r2);
a[i].p = (vec){(db)l1, (db)r1}, a[i].t = (vec){(db)(l2 - l1), (db)(r2 - r1)}, cnt = 0;
for (int j = 1; j < i; ++j) {
vec c = Cross(a[j], a[i]);
if (c.x == oo) continue;
db ds = Dist(c);
if (ds > r || Eq(ds, r)) continue;
cs[++cnt] = c;
}
sort(cs + 1, cs + cnt + 1, cmp);
int tot = 0; cs[cnt + 1].x = oo;
for (int i = 1; i <= cnt; ++i) if (cs[i] != cs[i + 1]) ++tot;
ans += tot + 1;
}
printf("%d\n", ans);
return 0;
}
(说了这么多就是把小于等于换成小于)
A3 第一次贪心贪对 85pts
好像做过类似的。。。显然要选尽量靠上的点。。就瞎xx贪。。
注意最后要特判根节点 (本来他以为他有爸爸罩着他结果发现他没爸爸)
然后就MLE了(1e+6空限64MB)
后来在linux平台上上改过了
#include<bits/stdc++.h>
#define R register int
using namespace std;
namespace Luitaryi {
inline int g() { R x=0,f=1;
register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*f;
} const int Inf=0x3f3f3f3f,N=1000010;
int n,k,ans,cnt,vr[N<<1],nxt[N<<1],fir[N],mx[N],mn[N];
inline void add(int u,int v) {
vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;
vr[++cnt]=u,nxt[cnt]=fir[v],fir[v]=cnt;
}
inline void dfs(int u,int fa) { mn[u]=Inf,mx[u]=0;
for(R i=fir[u];i;i=nxt[i]) {
if(vr[i]==fa) continue; dfs(vr[i],u);
mx[u]=max(mx[u],mn[vr[i]]+mx[vr[i]]<=k?0:mx[vr[i]]+1);
mn[u]=min(mn[u],mn[vr[i]]+1);
}
if(mn[u]+mx[u]<=k) mx[u]=0;
if(mx[u]>=k) ++ans,mn[u]=0,mx[u]=0;
}
inline void main() {
n=g(),k=g(); for(R i=1,u,v;i<n;++i) u=g(),v=g(),add(u,v);
dfs(1,0); if(mx[1]+mn[1]>k) ++ans; printf("%d\n",ans);
}
} signed main() {Luitaryi::main(); return 0;}
B1
二分。
#include<bits/stdc++.h>
#define R register int
using namespace std;
namespace Luitaryi {
inline int g() { R x=0,f=1;
register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*f;
} const int N=100010;
int n,m,x[N],y[N];
inline void main() {
n=g();
for(R i=1;i<=n;++i) x[i]=g();
for(R i=1;i<=n;++i) y[i]=g();
sort(x+1,x+n+1),sort(y+1,y+n+1);
m=g(); while(m--) {
R X=g(),Y=g(),l=0,r=n;
while(l<r) {
R md=l+r+1>>1;
if(1ll*Y*x[md]+1ll*X*y[md]>=1ll*x[md]*y[md]) l=md;
else r=md-1;
} printf("%d\n",l);
}
}
} signed main() {Luitaryi::main(); return 0;}
B2
倍增,维护链上最小值。
#include<bits/stdc++.h>
#define R register int
using namespace std;
namespace Luitaryi {
inline int g() { R x=0,f=1;
register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*f;
} const int N=100010,L=17,Inf=1e9;
int n,m,cnt;
int vr[N<<1],nxt[N<<1],fir[N],fa[N][L],mn[N][L],f[N];
struct node {int k,w; node() {} node(int _k,int _w) {k=_k,w=_w;}};
vector <node> mem[N];
inline void add(int u,int v) {
vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;
vr[++cnt]=u,nxt[cnt]=fir[v],fir[v]=cnt;
}
inline void dfs(int u) { f[u]=Inf;
for(R t=1;t<L;++t)
fa[u][t]=fa[fa[u][t-1]][t-1],
mn[u][t]=min(mn[u][t-1],mn[fa[u][t-1]][t-1]);
if(u!=1) for(R i=0,lim=mem[u].size();i<lim;++i) {
R k=mem[u][i].k,tmp=u,crt=Inf;
for(R t=L-1;~t;--t) if(k>=(1<<t))
crt=min(crt,mn[tmp][t]),tmp=fa[tmp][t],k-=(1<<t);
f[u]=min(f[u],crt+mem[u][i].w);
} if(u==1) f[u]=0;
for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
if(fa[v][0]) continue;
fa[v][0]=u,mn[v][0]=f[u],dfs(v);
}
}
inline void main() {
n=g(),m=g(); for(R i=1,u,v;i<n;++i) u=g(),v=g(),add(u,v);
for(R i=1,u,k,w;i<=m;++i) u=g(),k=g(),w=g(),mem[u].push_back(node(k,w));
dfs(1); m=g(); for(R i=1,u;i<=m;++i) u=g(),printf("%d\n",f[u]);
}
} signed main() {Luitaryi::main(); return 0;}
B3
模拟?
咕?
总结
不要写挂,稳稳稳。
注意精度,之前没有发现double这么。。。