这场梁大大怎么就用我小号打了啊??
然后就2个小时出场?然后rank15涨飞?
(dlsFST好惨啊)
Bark to Unlock
搞笑题,记得考虑原来就出现就不会FST。
#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
using namespace std;
char a[2],b[2];
int n,num[1000][2];
int read()
{
int x=1;
char ch;
while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
int s=ch-'0';
while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
return x*s;
}
int main()
{
a[0]=gc,a[1]=gc;
n=read();
for (int i=1;i<=n;i++)
{
while (b[0]=gc,b[0]<'a'||b[0]>'z');
b[1]=gc;
if (b[0]==a[0]&&b[1]==a[1])
{
puts("YES");
return 0;
}
num[b[0]][0]++,num[b[1]][1]++;
}
if (num[a[0]][1]&&num[a[1]][0]) puts("YES");
else puts("NO");
return 0;
}
Race Against Time
一百种方法的题目。
#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
using namespace std;
double a[3];
int read()
{
int x=1;
char ch;
while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
int s=ch-'0';
while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
return x*s;
}
int main()
{
int h,m,s,t1,t2;
h=read(),m=read(),s=read(),t1=read(),t2=read();
a[0]=(double)(h%12)+(double)m/60.0+(double)s/3600.0;
a[1]=(double)m/5.0+(double)s/300.0;
a[2]=(double)s/5.0;
sort(a,a+3);
if (t1>a[0]&&t1<a[1])
{
if (t2>a[0]&&t2<a[1]) puts("YES");
else puts("NO");
}
if (t1>a[1]&&t1<a[2])
{
if (t2>a[1]&&t2<a[2]) puts("YES");
else puts("NO");
}
if (t1<a[0]||t1>a[2])
{
if (t2<a[0]||t2>a[2]) puts("YES");
else puts("NO");
}
return 0;
}
Qualification Rounds
似乎总共就最多16种。dfs似乎就好了。(小猫代码)
#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
using namespace std;
int f[2][2][2][2],n,k,a[5],u[5],v[5],flag;
void dfs(int x)
{
if (x==5)
{
if (f[u[1]][u[2]][u[3]][u[4]]&&f[v[1]][v[2]][v[3]][v[4]])
flag=1;
return;
}
for (int i=0;i<=1;i++)
for (int j=0;j<=1;j++)
if (i+j!=2)
{
u[x]=i,v[x]=j;
dfs(x+1);
}
}
int main()
{
scanf("%d%d",&n,&k);
for (int i=1;i<=n;i++)
{
for (int j=1;j<=4;j++)
{
if (j<=k) scanf("%d",&a[j]);
else a[j]=0;
}
f[a[1]][a[2]][a[3]][a[4]]=1;
}
dfs(1);
puts(flag?"YES":"NO");
}
Huge Strings
答案最多8(应该挺好证)。然后就只要维护前后8个就好。
#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 109
#define M 8
using namespace std;
bitset<1<<M> pd[N<<1][M+1];
int n,m,l[N<<1][M+1],r[N<<1][M+1],len[N<<1],b[N],ret;
char str[N];
int read()
{
int x=1;
char ch;
while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
int s=ch-'0';
while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
return x*s;
}
int main()
{
n=read();
for (int i=1;i<=n;i++)
{
scanf("%s",str+1);
len[i]=strlen(str+1);
for (int j=1;j<=M;j++)
{
if (len[i]<j) break;
int now=0;
for (int k=1;k<j;k++) now=now<<1|(str[k]-'0');
for (int k=j;k<=len[i];k++)
{
now=(now<<1|(str[k]-'0'))&((1<<j)-1);
pd[i][j][now]=1;
}
}
for (int j=1;j<=min(len[i],M);j++)
l[i][j]=(str[j]-'0'),r[i][j]=(str[len[i]-j+1]-'0');
}
m=read();
while (m--)
{
int x=read(),y=read(),L=0;
for (int j=min(len[x],M);j;j--)
b[++L]=r[x][j];
for (int j=1;j<=min(len[y],M);j++)
b[++L]=l[y][j];
assert(L<=2*M);
len[++n]=len[x]+len[y],ret=0;
if (len[x]>M||len[y]>M||len[n]>M) len[n]=M+1;
if (len[n]<=M)
for (int i=1;i<=L;i++)
l[n][i]=b[i],r[n][i]=b[L-i+1];
else
{
for (int i=1;i<=min(len[x],M);i++)
l[n][i]=l[x][i];
if (len[x]<M)
for (int i=len[x]+1;i<=M;i++)
l[n][i]=l[y][i-len[x]];
for (int i=1;i<=min(len[y],M);i++)
r[n][i]=r[y][i];
if (len[y]<M)
for (int i=len[y]+1;i<=M;i++)
r[n][i]=r[x][i-len[y]];
}
for (int i=1;i<=M;i++)
{
pd[n][i]=pd[x][i]|pd[y][i];
if (L<i) continue;
int now=0;
for (int k=1;k<i;k++) now=now<<1|b[k];
for (int k=i;k<=L;k++)
{
now=(now<<1|b[k])&((1<<i)-1);
assert(now<(1<<i));
pd[n][i][now]=1;
}
}
for (int i=1;i<=M;i++)
{
bool flag=((int)pd[n][i].count()==(1<<i));
if (flag) ret=i;
else break;
}
printf("%d\n",ret);
}
return 0;
}
Policeman and a Tree
dp[x][y][z][w]
表示从
y
走到
#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 59
#define inf 0x3f3f3f3f
using namespace std;
int n,first[N],number,st,tg[N],m,fa[N],d[N],f[N][N];
int DP[N][N][N][N],Ans=inf;
struct edge
{
int to,next,val;
void add(int x,int y,int z)
{
to=y,next=first[x],first[x]=number,val=z;
}
}e[N<<1];
int read()
{
int x=1;
char ch;
while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
int s=ch-'0';
while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
return x*s;
}
int dp(int x,int y,int z,int w)
{
if (z==0&&w==0) return 0;
if (DP[x][y][z][w]) return DP[x][y][z][w];
if (d[x]==1)
{
if (z==0) return 0;
return DP[x][y][z][w]=dp(y,x,0,z)+f[x][y];
}
int g[N];
for (int i=1;i<=w;i++) g[i]=-inf;
g[0]=inf;
for (int i=first[x];i;i=e[i].next)
if (e[i].to!=y)
{
for (int j=w;j;j--)
for (int k=1;k<=j;k++)
g[j]=max(g[j],min(g[j-k],dp(e[i].to,x,z+w-k,k)+e[i].val));
}
return DP[x][y][z][w]=g[w];
}
void dfs(int x)
{
for (int i=first[x];i;i=e[i].next)
if (e[i].to!=fa[x])
{
fa[e[i].to]=x,dfs(e[i].to);
tg[x]+=tg[e[i].to];
}
}
int main()
{
n=read();
for (int i=1;i<n;i++)
{
int x=read(),y=read(),z=read();
e[++number].add(x,y,z);
e[++number].add(y,x,z);
d[x]++,d[y]++;
f[x][y]=f[y][x]=z;
}
st=read(),m=read();
for (int i=1;i<=m;i++) tg[read()]++;
dfs(1);
for (int i=first[st];i;i=e[i].next)
if (e[i].to==fa[st]) Ans=min(Ans,dp(e[i].to,st,tg[st],m-tg[st])+e[i].val);
else Ans=min(Ans,dp(e[i].to,st,m-tg[e[i].to],tg[e[i].to])+e[i].val);
printf("%d\n",Ans);
return 0;
}
Yet Another Minimization Problem
首先
dp[i][j]
表示前
j
个数分成
显然具有决策单调性。
分
k
层dp,考虑
#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 100009
#define inf (ll)0x3f3f3f3f3f3f3f3f
using namespace std;
ll n,k,a[N],dp[2][N],num[N],Ans,l=0,r=0;
struct node
{
ll l,r,x,y;
node(ll l=0,ll r=0,ll x=0,ll y=0):l(l),r(r),x(x),y(y){}
}q[N];
ll read()
{
ll x=1;
char ch;
while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
ll s=ch-'0';
while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
return x*s;
}
void add(ll x)
{
Ans+=(num[x]++);
}
void del(ll x)
{
Ans-=(--num[x]);
}
ll get(ll x,ll y)
{
while (r<y) add(a[++r]);
while (l>x) add(a[--l]);
while (r>y) del(a[r--]);
while (l<x) del(a[l++]);
return Ans+dp[0][x-1];
}
void solve()
{
ll L=1,R=1;
q[1]=node(1,n,1,n);
while (L<=R)
{
node now=q[L++];
ll mid=(now.l+now.r)>>1,m=now.x;
for (ll i=now.x;i<=now.y&&i<=mid;i++)
{
ll tmp=get(i,mid);
if (tmp<dp[1][mid]) dp[1][mid]=tmp,m=i;
}
if (now.l<mid) q[++R]=node(now.l,mid-1,now.x,m);
if (mid<now.r) q[++R]=node(mid+1,now.r,m,now.y);
}
}
int main()
{
n=read(),k=read();
for (ll i=1;i<=n;i++) a[i]=read();
memset(dp,inf,sizeof(dp));
dp[1][0]=0;
for (ll t=1;t<=k;t++)
{
for (ll i=0;i<=n;i++) dp[0][i]=dp[1][i];
memset(num,0,sizeof(num)),Ans=r=0,l=1;
solve();
}
printf("%lld\n",dp[1][n]);
return 0;
}
(G题似乎策略可以想到,然而完全不会写啊。有空再补吧)