北航2016集训队选拔赛答题报告
Preface
https://biancheng.love/contest-ng/index.html#/80
A zxa and split
Description
在一根长度无限的数轴上,有
每经过一年,一只zxa会分裂成两只,若它的坐标为
然而,由于生存空间有限,若一个位置上有不少于
经过测定,
请你预计,第
Input
输入包含多组测试数据,以EOF结束,不超过10组数据。
对于每组测试数据:
第一行包含三个整数
接下来
Output
对于每组测试数据输出一行,包含一个非负整数,表示第
Sample Input
2 2 2
0 3
1 2
Sample Output
3
Hint
题解
很容易发现是组合数,预处理下阶乘和逆元的前缀和,
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
using namespace std;
typedef long long LL;
const LL mod=1e9+7;
LL f[110000],inv[110000],ff[110000];
LL n,T,w;
LL C(int n,int m)
{
if (m>n) return 0;
LL res=(f[n]*inv[m])%mod;
res=(res*inv[n-m]) %mod;
return res;
}
int main()
{
f[0]=1;
for (int i=1;i<=100000;i++)
f[i]=(i*f[i-1])%mod;
ff[1]=ff[0]=inv[1]=inv[0]=1;
for (int i=2;i<=100000;i++)
{
inv[i]=(LL)(mod-mod/i)*inv[mod%i]%mod;
ff[i]=inv[i];
}
for (int i=2;i<=100000;i++)
{
inv[i]=(inv[i]*inv[i-1])%mod;
}
while (cin>>n>>T>>w)
{
LL ans=0;
for (int i=1;i<=n;i++)
{
LL x,y;
cin>>x>>y;
LL d=abs(w-x);
LL num=0;
if (T%2==0)
{
if (d%2==1) continue;
LL pos=T/2+1;
pos+=d/2;
num=(num+C(T,pos-1))%mod;
}
else
{
if (d%2==0) continue;
LL pos=(T+1)/2;
pos+=d/2;
num=(ans+C(T,pos-1))%mod;
}
num=(num*y)%mod;
ans=(ans+num)%mod;
}
printf("%lld\n",ans);
}
return 0;
}
B zxa and kids
Description
zxa马上就要毕业了!
作为一个即将离开BUAA的人,zxa想为母校再做一些微小的贡献,于是他计划带领北航幼儿园的小朋友出去玩。
zxa现在要带领
由于小朋友的年龄非常小,如果独自通过桥的话会有掉下去的危险,因此必须由zxa陪着他们来过河。
但是zxa的体重太大了,因此每次最多只能带一个小朋友到河对岸。也就是说,zxa只能带一个小朋友过河,之后再自己从桥上走回来带另一个小朋友过河。
现在已知北航幼儿园的小朋友有
但是zxa有独特的人格魅力,只要zxa在他们身边(和他们在同一个河岸上),他们就不会打架。
zxa想使所有小朋友都能够到河的对岸且在任意时刻都不会有小朋友打架,他想知道这能不能做到。
zxa觉得一个人来做太累了,他创建了
也就是说,最开始河的一岸有
Input
输入包含多组测试数据,以EOF结束,不超过30组数据。
对于每组测试数据:
第一行包含三个非负整数
接下来
Output
对于每组测试数据输出一行,如果zxa能完成这个任务则输出YES,否则输出NO。
Sample Input
2 1 0
0 1
Sample Output
YES
题解
若
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
using namespace std;
int n,m,k;
int last[210],e[1300],pre[1300];
int v[210],pp[210];
int xx,yy;
struct node
{
int x,y;
}a[610];
int cmp(node a,node b)
{
if (a.x!=b.x) return a.x<b.x;
return a.y<b.y;
}
int flag;
void dfs(int x,int y)
{
v[x]=y;
pp[x]=1;
for (int i=last[x];i>0;i=pre[i])
{
if (!pp[e[i]]&&e[i]!=xx&&e[i]!=yy) dfs(e[i],3-y);
else
{
if (v[e[i]]==v[x]&&e[i]!=xx&&e[i]!=yy)
{
flag=1;
break;
}
}
}
}
int main()
{
memset(e,0,sizeof(e));
while (scanf("%d %d %d",&n,&m,&k)==3)
{
memset(last,0,sizeof(last));
for (int i=1;i<=m;i++)
{
int x,y;
scanf("%d %d",&x,&y);
if (x>y) swap(x,y);
e[i*2]=y;
pre[i*2]=last[x];
last[x]=i*2;
e[i*2-1]=x;
pre[i*2-1]=last[y];
last[y]=i*2-1;
a[i].x=x,a[i].y=y;
}
sort(a+1,a+1+m,cmp);
int num=0;
if (k==0)
{
if (m!=0) num=1;
for (int i=2;i<=m;i++)
{
if (a[i].x!=a[i-1].x||a[i].y!=a[i-1].y) num++;
}
if (num>1) printf("NO\n");
else printf("YES\n");
}
else if (k==1)
{
int fflag=0;
for (int i=0;i<n;i++)
for (int j=i+1;j<n;j++)
{
memset(v,0,sizeof(v));
memset(pp,0,sizeof(pp));
flag=0;
xx=i,yy=j;
for (int l=0;l<n;l++)
{
if (l==i||l==j) continue;
if (!pp[l])
{
dfs(l,1);
}
}
if (!flag)
{
fflag=1;
break;
}
}
if (fflag) printf("YES\n");
else printf("NO\n");
}
else printf("YES\n");
}
return 0;
}
C zxa and UAV
Description
真是一个悲伤的故事,zxa的肾飞走了。取而代之,飞回来的是一个UAV(Unmanned Aerial Vehicle)。可恨的是UAV上面却写着sd0061!!!
后来才知道,sd0061就是zxa本人。
sd0061作为zxa的绰号相似度太低,让人非常难以辨认。所以,这并不是一个好绰号。
我们定义两个字符串的相似度是他们的最长公共前缀的长度。
现在给你
Input
输入包含多组测试数据,以EOF结束,不超过10组数据。
对于每组测试数据:
第一行包含一个正整数
接下来
接下来
Output
对于每组测试数据输出一行,包含一个非负整数,表示搭配的最大相似度。
Sample Input
5
gennady
galya
boris
bill
toshik
bilbo
torin
gendalf
smaug
galadriel
Sample Output
11
题解
贪心,对两组串分别建立两颗trie树,然后记录trie上每个位置在串中出现的次数。然后求两个trie树对应点min值之和即可。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
using namespace std;
const int CHARSET=26,BASE='a',MAX_NODE=510000;
struct Trie
{
int tot,root,child[MAX_NODE][CHARSET];
int cnt[MAX_NODE];
Trie()
{
memset(child[1],0,sizeof(child[1]));
memset(cnt,0,sizeof(cnt));
root=tot=1;
}
void clear()
{
memset(child[1],0,sizeof(child[1]));
memset(cnt,0,sizeof(cnt));
root=tot=1;
}
void insert(const char *str)
{
int *cur=&root;
for (const char *p=str;*p;++p)
{
cur=&child[*cur][*p-BASE];
if (*cur==0)
{
*cur=++tot;
memset(child[tot],0,sizeof(child[tot]));
}
cnt[*cur]++;
}
}
}S,T;
int n;
char s[1100000];
int ans;
void dfs(int x,int y)
{
ans+=min(S.cnt[x],T.cnt[y]);
for (int i=0;i<26;i++)
{
if (S.cnt[S.child[x][i]]!=0&&T.cnt[T.child[y][i]]!=0) dfs(S.child[x][i],T.child[y][i]);
}
}
int main()
{
while (scanf("%d",&n)==1)
{
S.clear();
T.clear();
for (int i=1;i<=n;i++)
{
scanf("%s",s);
S.insert(s);
}
for (int i=1;i<=n;i++)
{
scanf("%s",s);
T.insert(s);
}
ans=0;
dfs(1,1);
printf("%d\n",ans);
}
return 0;
}
D zxa and tree
Description
zxa来到了一棵树面前,他觉得这棵树太单调了,所以决定给树染上黑白两种颜色。
树有
现在zxa想知道,对于每个非负整数
Input
输入包含多组测试数据,以EOF结束,不超过10组数据。
对于每组测试数据:
第一行包含一个正整数
接下来
接下来一行包含
接下来一行包含
Output
对于每组测试数据输出一行,包含
Sample Input
3
1 2
2 3
1 1 1
2 2 2
10
8 1
1 9
9 7
1 2
7 10
8 5
7 3
2 6
8 4
10 2 7 2 9 2 6 1 2 10
10 4 8 9 5 5 10 3 2 10
Sample Output
6 8 7 3
66 99 123 138 147 146 142 133 113 87 51
题解
树上dp,首先我们需要枚举总共的白点个数。然后在树上进行dp。记录状态为
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<bitset>
using namespace std;
int n;
int a[110],b[110];
int e[210],pre[210],last[110],pp[110];
int f[110][110];
int g[110][110];
int nu[110];
int tot;
void work(int x)
{
pp[x]=1;
for (int i=last[x];i;i=pre[i])
{
if (!pp[e[i]])
{
work(e[i]);
for (int j=0;j<=min(nu[x]+nu[e[i]],tot);j++)
g[x][j]=0;
for (int j=0;j<=nu[x];j++)
for (int k=0;k<=min(nu[e[i]],max(0,tot-j));k++)
{
g[x][j+k]=max(g[x][j+k],f[x][j]+f[e[i]][k]);
}
for (int j=0;j<=min(nu[x]+nu[e[i]],tot);j++)
f[x][j]=g[x][j];
nu[x]+=nu[e[i]];
}
}
nu[x]++;
for (int j=0;j<=min(nu[x],tot);j++)
{
g[x][j]=0;
if (j!=0) g[x][j]=max(g[x][j],f[x][j-1]+a[x]);
if (j!=nu[x]) g[x][j]=max(g[x][j],f[x][j]+b[x]);
}
for (int i=0;i<=min(nu[x],tot);i++)
f[x][i]=g[x][i]+i*((n-tot)-(nu[x]-i))+(nu[x]-i)*(tot-i);
}
int main()
{
while (scanf("%d",&n)==1)
{
memset(last,0,sizeof(last));
memset(nu,0,sizeof(nu));
for (int i=1;i<n;i++)
{
int x,y;
scanf("%d %d",&x,&y);
e[i*2]=y;
pre[i*2]=last[x];
last[x]=i*2;
e[i*2-1]=x;
pre[i*2-1]=last[y];
last[y]=i*2-1;
}
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=0;i<=n;i++)
{
memset(pp,0,sizeof(pp));
memset(f,0,sizeof(f));
memset(nu,0,sizeof(nu));
tot=i;
work(1);
printf("%d",f[1][i]);
if (i==n) printf("\n");
else printf(" ");
}
}
return 0;
}
E zxa and path
Description
zxa有一个无向图,含有
zxa对单源最短路径产生了兴趣,所以他算出了从点
zxa很好奇,对于每一个点
你能帮助他算出
Input
输入包含多组测试数据,以EOF结束,不超过20组数据。
对于每组测试数据:
第一行包含两个正整数
接下来
接下来一行包含
对于任意的一点
Output
对于每组测试数据输出一行,包含
Sample Input
2 1
1 2 1
1
4 5
1 2 2
1 3 2
2 3 1
2 4 3
3 4 4
1 2 4
5 9
1 2 6
1 3 3
1 4 2
2 3 2
2 3 4
2 5 3
3 5 1
3 5 2
4 5 4
2 3 4 7
Sample Output
-1
3 3 6
6 7 8 5
题解
首先建立最短路径树,求出
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
using namespace std;
const int INF=1e9;
int pp[4100];
int x[110000],y[110000],w[110000];
int e[210000],last[4100],cost[210000],pre[210000],use[210000];
int cx[110000];
int fa[210000];
int dis[110000],sh[110000];
int n,m;
int nnum;
int rm[310000];
int dd[110000];
int father[110000];
void dfs(int x,int sum,int depth)
{
nnum++;
pp[x]=1;
cx[x]=nnum;
dis[x]=sum;
sh[x]=depth;
rm[nnum]=x;
for (int i=last[x];i;i=pre[i])
{
if (!pp[e[i]])
{
fa[e[i]]=x;
dfs(e[i],sum+cost[i],depth+1);
nnum++;
rm[nnum]=x;
}
}
}
struct edge
{
int u,v,w;
}a[110000];
int cmp(edge a,edge b)
{
return a.w<b.w;
}
int num;
const int MAX=110000;
int stTable[MAX][32];
int preLog2[MAX];
void st_prepare(int n,int *array)
{
preLog2[1]=0;
for (int i=2;i<=n;i++)
{
preLog2[i]=preLog2[i-1];
if ((1<<preLog2[i]+1)==i)
{
preLog2[i]++;
}
}
for (int i=n-1;i>=0;i--)
{
stTable[i][0]=array[i];
for (int j=1;(i+(1<<j)-1)<n;j++)
{
if (sh[stTable[i][j-1]]<sh[stTable[i+(1<<j-1)][j-1]]) stTable[i][j]= stTable[i][j-1];
else stTable[i][j]= stTable[i+(1<<j-1)][j-1];
}
}
}
int query_min(int l,int r)
{
if (l>r) swap(l,r);
int len=r-l+1,k=preLog2[len];
if (sh[stTable[l][k]]<sh[stTable[r-(1<<k)+1][k]]) return stTable[l][k];
else return stTable[r-(1<<k)+1][k];
}
int lca(int x,int y)
{
return query_min(cx[x],cx[y]);
}
int getfather(int x)
{
if (father[x]==x) return x;
else father[x]=getfather(father[x]);
return father[x];
}
int main()
{
while (scanf("%d %d",&n,&m)==2)
{
memset(last,0,sizeof(last));
memset(use,0,sizeof(use));
for (int i=1;i<=m;i++)
{
scanf("%d %d %d",&x[i],&y[i],&w[i]);
}
for (int i=1;i<=n-1;i++)
{
int xx;
scanf("%d",&xx);
use[xx]=1;
e[i*2]=y[xx];
pre[i*2]=last[x[xx]];
last[x[xx]]=i*2;
e[i*2-1]=x[xx];
pre[i*2-1]=last[y[xx]];
last[y[xx]]=i*2-1;
cost[2*i]=cost[2*i-1]=w[xx];
}
nnum=0;
memset(pp,0,sizeof(pp));
dfs(1,0,1);
st_prepare(nnum,rm);
num=0;
for (int i=1;i<=m;i++)
{
if (!use[i])
{
num++;
a[num].u=x[i],a[num].v=y[i],a[num].w=dis[x[i]]+dis[y[i]]+w[i];
}
}
for (int i=2;i<=n;i++)
dd[i]=INF;
sort(a+1,a+1+num,cmp);
for (int i=1;i<=n;i++)
father[i]=i;
for (int i=1;i<=num;i++)
{
int p=lca(a[i].u,a[i].v);
int f=getfather(a[i].u);
while (sh[f]>sh[p])
{
father[f]=getfather(fa[f]);
dd[f]=a[i].w-dis[f];
f=father[f];
}
f=getfather(a[i].v);
while (sh[f]>sh[p])
{
father[f]=getfather(fa[f]);
dd[f]=a[i].w-dis[f];
f=father[f];
}
}
for (int i=2;i<=n;i++)
{
if (dd[i]==INF) printf("-1");
else printf("%d",dd[i]);
if (i!=n) printf(" ");
else printf("\n");
}
}
return 0;
}
F zxa and xor
Description
zxa有一个长度为
其中
你需要给出对序列进行
Input
zxa有一个长度为
其中
你需要给出对序列进行
Output
对于每组测试数据输出多行,其中对于每一种询问操作输出一行,包含一个非负整数,表示相应的答案。
Sample Input
1
10
1 0 0 1 0 0 1 0 1 1
4
0 1 3
1 2 5
2 3
1 2 5
Sample Output
3
6
4
题解
求出前缀和,用线段树维护区间内有多少前缀和为
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
using namespace std;
typedef long long LL;
int a[210000];
struct Seg
{
struct data
{
int l,r,lazy;
int n0,n1;
}tr[2100000];
void update(int k)
{
pushdown(k<<1);
pushdown(k<<1|1);
tr[k].n0=tr[k<<1].n0+tr[k<<1|1].n0;
tr[k].n1=tr[k<<1].n1+tr[k<<1|1].n1;
}
void pushdown(int k)
{
if (tr[k].lazy)
{
swap(tr[k].n0,tr[k].n1);
if (tr[k].l!=tr[k].r) tr[k<<1].lazy^=1,tr[k<<1|1].lazy^=1;
tr[k].lazy=0;
}
}
void build(int k,int l,int r)
{
tr[k].l=l,tr[k].r=r;
tr[k].lazy=0;
if (l==r)
{
if (a[l]==0) tr[k].n0=1,tr[k].n1=0;
else tr[k].n1=1,tr[k].n0=0;
return ;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
update(k);
}
void lchange(int k,int a,int b)
{
int l=tr[k].l,r=tr[k].r;
pushdown(k);
if (a==l&&b==r)
{
tr[k].lazy^=1;
pushdown(k);
return ;
}
int mid=(l+r)>>1;
if (b<=mid) lchange(k<<1,a,b);
else if (a>mid) lchange(k<<1|1,a,b);
else lchange(k<<1,a,mid),lchange(k<<1|1,mid+1,b);
update(k);
}
int lask(int k,int a,int b,int c)
{
pushdown(k);
int l=tr[k].l,r=tr[k].r;
if (a==l&&b==r)
{
if (c==0) return tr[k].n0;
else return tr[k].n1;
}
int mid=(l+r)>>1;
int tmp;
if (b<=mid) tmp=lask(k<<1,a,b,c);
else if (a>mid) tmp=lask(k<<1|1,a,b,c);
else tmp=lask(k<<1,a,mid,c)+lask(k<<1|1,mid+1,b,c);
update(k);
return tmp;
}
}T;
int q;
LL ans;
int n;
int main()
{
int cas;
scanf("%d",&cas);
while (cas--)
{
scanf("%d",&n);
for (int i=2;i<=n+1;i++)
scanf("%d",&a[i]),a[i]^=a[i-1];
n++;
T.build(1,1,n);
scanf("%d",&q);
for (int i=1;i<=q;i++)
{
int op,x,y;
scanf("%d",&op);
if (op==0)
{
scanf("%d %d",&x,&y);
x++,y++;
LL cf=0;
int l0=T.lask(1,x-1,y-1,0),l1,r0=T.lask(1,x,y,0),r1;
l1=(y-x+1-l0);
r1=(y-x+1-r0);
ans=(LL)l0*(LL)r0+(LL)l1*(LL)r1;
if (x!=y)
{
int xx=T.lask(1,x,y-1,0),yy;
yy=(y-x-xx);
cf=((LL)xx*(LL)xx+(LL)yy*(LL)yy+(LL)y-(LL)x)/2LL;
}
ans-=cf;
printf("%lld\n",ans);
}
else if (op==1)
{
scanf("%d %d",&x,&y);
x++,y++;
LL cf=0;
int l0=T.lask(1,x-1,y-1,0),l1,r0=T.lask(1,x,y,0),r1;
l1=(y-x+1-l0);
r1=(y-x+1-r0);
ans=(LL)l0*(LL)r1+(LL)l1*(LL)r0;
if (x!=y)
{
int xx=T.lask(1,x,y-1,0),yy;
yy=(y-x-xx);
cf=((LL)xx*(LL)yy+(LL)xx*(LL)yy)/2LL;
}
ans-=cf;
printf("%lld\n",ans);
}
else
{
scanf("%d",&x);
x++;
T.lchange(1,x,n);
}
}
}
return 0;
}
G zxa and robot
Description
zxa在二维平面上放置了一个机器人,初始坐标为
现在zxa想要让机器人走到
Input
输入包含多组测试数据,以EOF结束,不超过10组数据。
每组测试数据仅占一行,包含两个整数
Output
对于每组测试数据输出一行,包含一个整数,代表到达目标点至少需要的步数,如果不存在到
Sample Input
8 3
1 1
Sample Output
3
-1
Hint
对于第一个样例,一种可行的最少步数的方案 是
题解
将x和y取绝对值后转化为
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
using namespace std;
typedef long long LL;
LL a[100],b[100];
int pp[100];
int n1,n2;
LL x,y;
int main()
{
while (cin>>x>>y)
{
x=abs(x),y=abs(y);
memset(pp,0,sizeof(pp));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
int num=0;
n1=n2=0;
while (x>0)
{
n1++;
a[n1]=x%3;
x/=3;
}
while (y>0)
{
n2++;
b[n2]=y%3;
y/=3;
}
int flag=0;
int pos;
int tt=0;
for (int i=1;;i++)
{
if (pp[i]) continue;
if (a[i]*b[i]!=0)
{
tt=1;
break;
}
if (a[i]+b[i]==0)
{
flag=1;
pos=i;
break;
}
if (a[i]==1)
{
pp[i]=1;
}
else if (a[i]==2)
{
pp[i]=1;
a[i+1]++;
int d=i+1;
while (a[d]==3)
{
a[d+1]++;
a[d]=0;
d++;
}
}
else if (b[i]==1)
{
pp[i]=1;
}
else
{
pp[i]=1;
b[i+1]++;
int d=i+1;
while (b[d]==3)
{
b[d+1]++;
b[d]=0;
d++;
}
}
}
if (tt)
{
printf("-1\n");
continue;
}
if (flag)
{
int fflag=0;
for (int i=pos;i<100;i++)
{
if (a[i]+b[i]!=0)
{
fflag=1;
break;
}
}
if (fflag) printf("-1\n");
else printf("%d\n",pos-1);
}
else printf("%d\n",pos-1);
}
return 0;
}
H zxa and array
Description
zxa有一个数组
幸运的是,zxa知道
问有多少个不同的数组
Input
输入包含多组测试数据,以EOF结束,不超过10组数据。
对于每组测试数据:
第一行包含一个正整数
第二行包含
Output
对于每组测试数据输出一行,包含一个非负整数,表示答案对
Sample Input
3
4 2 2
3
2 2 2
Sample Ouput
4
0
Hint
对于第一个样例,可能的aa有
题解
将
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
using namespace std;
typedef long long LL;
const LL mod=1e9+7;
LL a[1100];
int n;
int main()
{
while (cin>>n)
{
for (int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+1+n);
LL ans=a[1];
for (int i=2;i<=n;i++)
ans=(ans*max(a[i]-i+1,0LL))%mod;
cout<<ans<<endl;
}
return 0;
}
I zxa and jing’a
Description
zxa有一个只包含
花费
花费
每种操作可以使用无限次,求把这个序列排成非降序列的最小花费。
Input
输入包含多组测试数据,以EOF为结尾,不超过80组数据。
对于每组测试数据:
第一行包含两个非负整数
第二行包含
Output
对于每组测试数据输出一行,包含一个非负整数,表示将这个序列排序的最小花费。
Sample Input
3 1
1 1 1
4 0
1 1 0 1
8 1
1 1 0 1 0 1 0 0
Sample Output
0
1
3
Hint
劲啊!
题解
很容易发现,排序操作是没有用的。所以直接统计有多少个不在正确位置上的0即可。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<bitset>
using namespace std;
int n,A;
int a[110000];
int num,ans;
int main()
{
while (scanf("%d %d",&n,&A)==2)
{
num=ans=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if (a[i]==0) num++;
}
for (int i=1;i<=n;i++)
{
if (a[i]==0&&i>num) ans++;
}
printf("%d\n",ans);
}
return 0;
}