Codeforces Global Round 16 题解
Posted yeah17981
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Global Round 16 题解相关的知识,希望对你有一定的参考价值。
传送门:Dashboard - Codeforces Global Round 16 - Codeforces
老鸽子终于记得更新了2333
A. Median Maximization
给n,m,构造出一个非负的递增数列,使其中的元素个数为n,元素和为m,求这些数列的中位数的最大值(此处中位数的定义为2k+1的第k+1个,2k的第k个)
1 5➡5 2 5➡2 3 3 5➡0 2 3 2 1➡无解 7 17➡0 0 0 4 4 4 5 4 14➡0 3 4 4 1 1000000000➡1000000000 1000000000 1➡无解
很显然,为了让中位数尽量大,中位数前后都要尽可能的小,简单找个规律就能发现答案了
#include<bits/stdc++.h>
using namespace std;
int t,n,m,k;
int main() {
cin>>t;
while(t--)
{
cin>>n>>m;
if(n%2==0)
k=n/2-1;
else
k=n/2;
n=n-k;
cout<<m/n<<"\\n";
}
}
B. MIN-MEX Cut
给一个01串,可以把它分割也可以不操作,求字串的mex和
mex值是字串中没用出现过的第一个自然数
很容易得知,不操作的时候mex=2
mex(0……0)=1
mex(1……1)=0
直接将0……0找出来就行
结果和2对比取最小
#include<bits/stdc++.h>
using namespace std;
int t,n,m,k;
char a[200000];
int main() {
cin>>t;
while(t--)
{
cin>>a;
int len=strlen(a);
int sum=0;
for(int i=0;i<len;i++)
{
if(a[i]=='0'&&(a[i+1]=='1'||i==len-1))
{
sum++;
}
}
cout<<min(sum,2)<<"\\n";
}
}
C
两个并列的01串,竖着切几刀将其分割,求分割了之后的mex和最大值
首先把每一位都分割开来,有1/0、0/0、1/1三种情况mex值为2,1,0
第一种情况和前后结合都会使总和变小
后两种情况结合起来使得总和变大
每种情况自己结合都使得总和变小
综上
先按位分割
再适当结合
#include<bits/stdc++.h>
using namespace std;
int t,n,m,a1,b1;
char a[200000],b[200000];
int c[200000],k[200000];
int main()
{
cin>>t;
while(t--)
{
cin>>n;
cin>>a>>b;
// int len=strlen(a);
int sum=0;
for(int i=0;i<n;i++)
{
k[i]=0;
a1=a[i]-'0';
b1=b[i]-'0';
if(a1+b1==1)//情况1
{
c[i]=2;
}
if(a1+b1==2)//情况3
{
c[i]=0;
}
if(a1+b1==0)//情况2
{
c[i]=1;
}
}
for(int i=0;i<n;i++)
{
if(c[i]==1)//先前后后
{
if(i!=0&&c[i-1]==0&&k[i-1]==0)
{
c[i]=2;
k[i-1]=1;//k用于标记此位是否已经被结合
}
else
{
if(i!=n-1&&c[i+1]==0&&k[i+1]==0)
{
c[i]=2;
k[i+1]=1;
}
}
}
}
for(int i=0;i<n;i++)
{
sum+=c[i];
}
cout<<sum<<"\\n";
}
return 0;
}
D1
给m个人的视力值,可能相同可能不同,这m个人坐在1-m的座位(同一排),视力值越小的人的位置值越小,每个人按顺序进场从位置1坐到自己的位置上,求越过的人次的总和的最小值
如果某个人的视力值和所有人都不同,那么他的位置是唯一的
如果有k个人的视力值相同,将他们单独抓出来看,越早进场的人坐到越后面,就不会越过相同视力的人
因此每个人按照从小到大视力排列,相同视力的时候按照id从大到小排列,此时得到每个人的座位值
再按照id排序,模拟进场,并求已经进场的座位值比第i个人的座位值的个数,可用树状数组求
(为啥最近老是喜欢用树状数组orz)
#include <bits/stdc++.h>
using namespace std;
int n,m;
int g[50005]; //对应原数组和树状数组
int lowbit(int x){
return x&(-x);
}
void updata(int i,int k,int m){ //在i位置加上k
while(i <= m){
g[i] += k;
i += lowbit(i);
}
}
int getsum(int i){ //求A[1 - i]的和
int res = 0;
while(i > 0){
res += g[i];
i -= lowbit(i);
}
return res;
}
struct xd{
int a,b,c;//a 视力 b 顺序 c 位置
};
xd z[600];
int cmp(xd y,xd x)
{
if(y.a==x.a) return y.b>x.b;
return y.a<x.a;
}
int cmp2(xd y,xd x)
{
return y.b<x.b;
}
int main(){
int t,n,m,sum,q;
cin>>t;
while(t--)
{
memset(g, 0, sizeof g);
sum=0;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>z[i].a;
z[i].b=i;
}
sort(z+1,z+1+m,cmp);
for(int i=1;i<=m;i++)
{
z[i].c=i;
}
sort(z+1,z+1+m,cmp2);
for(int i=1;i<=m;i++)//a 视力 b 顺序 c 位置
{
q=getsum(z[i].c);
sum+=q;
updata(z[i].c,1,m); //输入初值的时候,也相当于更新了值
}
cout<<sum<<"\\n";
}
return 0;
}
D2
多了个n行,此时第一次排序按照视力从小到大,id从小到大排序
再分别在每排排序,按照视力从小到大,id从大到小排序
求出位置值
然后同上
#include <bits/stdc++.h>
using namespace std;
int n,m;
int g[600][600]; //对应原数组和树状数组
int lowbit(int x){
return x&(-x);
}
void updata(int i,int k,int m,int l){ //在i位置加上k
while(i <= m){
g[i][l] += k;
i += lowbit(i);
}
}
int getsum(int i,int l){ //求A[1 - i]的和
int res = 0;
while(i > 0){
res += g[i][l];
i -= lowbit(i);
}
return res;
}
struct xd{
int a,b,c;//a 视力 b 顺序 c 位置
};
xd z[360000];
int cmp(xd y,xd x)
{
if(y.a==x.a) return y.b>x.b;
return y.a<x.a;
}
int cmp2(xd y,xd x)
{
return y.b<x.b;
}
int cmp3(xd y,xd x)
{
if(y.a==x.a) return y.b<x.b;
return y.a<x.a;
}
int main(){
long long t,n,m,sum,q,p;
cin.tie(0);
ios::sync_with_stdio(false);
cin>>t;
while(t--)
{
memset(g, 0, sizeof g);
sum=0;
cin>>n>>m;
for(int i=1;i<=m*n;i++)
{
cin>>z[i].a;
z[i].b=i;
}
sort(z+1,z+1+m*n,cmp3);
for(int i=1;i<=n;i++)
{
sort(z+1+(i-1)*m,z+1+i*m,cmp);
for(int j=1;j<=m;j++)
{
z[(i-1)*m+j].c=(i-1)*m+j;
}
}
sort(z+1,z+1+m*n,cmp2);
for(int i=1;i<=m*n;i++)//a 视力 b 顺序 c 位置 n排m列
{
if(z[i].c%m==0) //q 行 p列
{
q=z[i].c/m;
p=m;
}
else
{
q=z[i].c/m+1;
p=z[i].c%m;
}
sum+=getsum(p,q);
updata(p,1,m,q); //输入初值的时候,也相当于更新了值
}
cout<<sum<<"\\n";
}
return 0;
}
后面懒得补了下次吧
以上是关于Codeforces Global Round 16 题解的主要内容,如果未能解决你的问题,请参考以下文章