2018.7.5模拟赛
我是咸鱼啊啊啊啊
我再也不交卷前1S改代码了,会-1s
题面见文件。
T1
考场代码,毫无美感。
在逆推的时候应该除19,而非20(ryc:啊我也不知道为什么).
因为是逆推,所以前一个点是这个点的 20/19
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
using namespace std;
const int N=50005;
int n,p,S,T,dis[300],head[505],ecnt;
struct Edge {
int to,nxt,val;
} e[52*52*3+5];
void add(int bg,int ed) {
e[++ecnt].nxt=head[bg];
e[ecnt].to=ed;
head[bg]=ecnt;
}
bool ck[200],vis[N];
queue<int>q;
int CNT;
void spfa() {
memset(dis,0x3f,sizeof dis);
q.push(T);
dis[T]=p;
vis[T]=1;
while(!q.empty()) {
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u]; i; i=e[i].nxt) {
int v=e[i].to;
if(ck[u]) {
int tp=dis[u]+ceil((double)dis[u]/19.0);
if(dis[v]>tp) {
dis[v]=tp;
if(!vis[v])vis[v]=1,q.push(v);
}
} else {
if(dis[v]>dis[u]+1) {
dis[v]=dis[u]+1;
if(!vis[v]) {
vis[v]=1,q.push(v);
}
}
}
}
}
}
int main() {
freopen("toll.in","r",stdin);
freopen("toll.out","w",stdout);
for(int i='A'; i<='Z'; i++) ck[i]=1;
while(1) {
char a,b;
CNT++;
memset(head,0,sizeof head);
ecnt=0;
scanf("%d",&n);
if(n==-1)return 0;
for(int i=1; i<=n; i++) {
scanf(" %c %c",&a,&b);
add(b,a);
add(a,b);
}
cin>>p>>a>>b;
S=a,T=b;
spfa();
printf("Case %d: %d\n",CNT,dis[S]);
}
}
T2
一道貌似网络流的题,考场最后一秒改了边权,80->20 &^%$#@!
实际上是最长上升子序列。
因为给每个逆序对之间连一条边,那么反证,如果选的不是LIS,那么一定会导致另一个或多个数被连边,会导致ans更差。
#include <bits/stdc++.h>
using namespace std;
int n;
const int N=2005,inf=0x3f3f3f3f,S=2003,T=2001;
int a[100005],h[100005],ecnt=1,head[100005];
struct Edge {
int to,nxt,val;
} e[N*N<<1];
void add(int bg,int ed,int val) {
e[++ecnt].nxt=head[bg];
e[ecnt].to=ed;
e[ecnt].val=val;
head[bg]=ecnt;
}
queue<int>q;
bool bfs() {
memset(h,-1,sizeof h);
q.push(S);
h[S]=0;
while(!q.empty()) {
int u=q.front();
q.pop();
for(int i=head[u]; i; i=e[i].nxt) {
int v=e[i].to;
if(h[v]==-1&&e[i].val) {
h[v]=h[u]+1;
q.push(v);
}
}
}
return h[T]!=-1;
}
int dfs(int x,int f) {
if (x==T)return f;
int tp,used=0;
for(int i=head[x]; i; i=e[i].nxt) {
int v=e[i].to;
if(e[i].val&&h[v]==h[x]+1) {
tp=dfs(v,min(f-used,e[i].val));
used+=tp;
e[i].val-=tp;
e[i^1].val+=tp;
if(used==f) return f;
}
}
if(!used) h[x]=-1;
return used;
}
int maxflow;
int t[100005<<2];
void add(int x,int Max) {
for(; x<=100005*3; x+=x&-x) {
t[x]=max(t[x],Max);
}
}
int ask(int x) {
int Max=-1;
for(; x; x-=x&-x)
Max=max(Max,t[x]);
return Max;
}
int f[100005<<2];
void dinic() {
while(bfs())maxflow+=dfs(S,inf);
}
void insert(int a,int b,int c) {
add(a,b,c);
add(b,a,0);
}
int main() {
freopen("sort.in","r",stdin);
freopen("sort.out","w",stdout);
scanf("%d",&n);
if(n<=1000) {
for(int i=1; i<=n; i++) scanf("%d",&a[i]);
for(int i=1; i<=n; i++) {
for(int j=i+1; j<=n; j++) {
if(a[i]>a[j]) add(i,j+n,inf),add(j+n,i,0);
}
}
for(int i=1; i<=n; i++) insert(S,i,1),insert(i+n,T,1);
dinic();
cout<<n-maxflow;
return 0;
} else {
int ans=1;
for(int i=1; i<=n; i++) {
int x;scanf("%d",&x);
f[i]=ask(x)+1;
ans=max(ans,f[i]);
add(x,f[i]);
}
printf("%d",ans);
}
}
失败的数据分治。
T3
唯一的水题,就是细节有点多。
状压dp,判一下能不能执行,因为每次执行相同密室后的结果一定相同,所以ans一定不变。
tip:发现不可行的时候,我这个写法是不能清零的,因为如果清零那么可能之前执行成功过。(GhostCai实测WA2个点)
我就是要压行
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,a[25],b[25],c[25],d[25],e[25],k1,k2,k3;
struct F {
int a1,a2,a3;
} f[1<<15];
int main() {
freopen("room.in","r",stdin);
freopen("room.out","w",stdout);
scanf("%d",&n);
for(int i=1; i<=n; i++) scanf("%d",&a[i]);
for(int i=1; i<=n; i++) scanf("%d",&b[i]);
for(int i=1; i<=n; i++) scanf("%d",&c[i]);
for(int i=1; i<=n; i++) scanf("%d",&d[i]);
for(int i=1; i<=n; i++) scanf("%d",&e[i]);
scanf("%d%d%d",&k1,&k2,&k3);
f[0].a2=k2,f[0].a1=k1,f[0].a3=k3;
for(int i=0; i<(1<<n); i++) {
for(int j=1; j<=n; j++) {
if(!((1<<j-1)&i)) {
if(a[j]>f[i].a1) {
if(a[j]>f[i].a1+f[i].a3) continue;
else {
if(f[i].a2<b[j]) {
if(f[i].a3-(a[j]-f[i].a1)+f[i].a2<b[j]) continue;
else f[i|(1<<j-1)].a1=0,f[i|(1<<j-1)].a2=0,f[i|(1<<j-1)].a3=(f[i].a3-(a[j]-f[i].a1)-(b[j]-f[i].a2));
} else f[i|(1<<j-1)].a1=0,f[i|(1<<j-1)].a2=f[i].a2-b[j],f[i|(1<<j-1)].a3=f[i].a3-(a[j]-f[i].a1);
}
} else {
if(b[j]>f[i].a2) {
if(b[j]>f[i].a2+f[i].a3) continue;
f[i|(1<<j-1)].a1=f[i].a1-a[j],f[i|(1<<j-1)].a2=0,f[i|(1<<j-1)].a3=f[i].a3-(b[j]-f[i].a2);
} else {
f[i|(1<<j-1)].a1=f[i].a1-a[j],f[i|(1<<j-1)].a2=f[i].a2-b[j];
f[i|(1<<j-1)].a3=f[i].a3;
}
}
f[i|(1<<j-1)].a1+=c[j];
f[i|(1<<j-1)].a2+=d[j];
f[i|(1<<j-1)].a3+=e[j];
}
}
}
int ans=-1;
for(int i=0; i<(1<<n); i++) ans=max(ans,f[i].a1+f[i].a2+f[i].a3);
cout<<ans;
}
我是咸鱼。转载博客请征得博主同意Orz