目录
AC篇:
A:
题意:
给出两个正数n,s,将s分割为n个非严格递增非负数,求中位数最大值。
思路:
使中位数左边(不包括中位数)全为0,右边(包括中位数)平均一下。
题解:
#include <bits/stdc++.h>
#define bbn 200005
#define maxint 2147483647
#define maxLLint 9223372036854775807
#define mod 1000000007 //1e9+7
const double eps=1e-7;
typedef long long int LL;
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
LL a,b;
cin>>a>>b;
LL k=a/2;
if(a%2==0) k--;
cout<<b/(a-k)<<endl;
}
}
B:
题意:
给出一个01串,求(可将01串分割计算)它的最小MEX。
思路:
判断连续0串的个数q。
q==0 输出为0
q==1 输出为1
q>=2 输出为2
题解:
#include <bits/stdc++.h>
#define bbn 200005
#define maxint 2147483647
#define maxLLint 9223372036854775807
#define mod 1000000007 //1e9+7
const double eps=1e-7;
typedef long long int LL;
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
string s;
cin>>s;
int q=0;
for(int i=0; i<s.size(); i++)
{
if(s[i]=='0')
{
for(int j=i; j<s.size(); j++)
{
if(s[j]=='1'||j==s.size()-1)
{
q++;
i=j;
break;
}
}
}
}
if(q==0)
{
cout<<0<<endl;
}
else if(q==1)
{
cout<<1<<endl;
}
else
{
cout<<2<<endl;
}
}
}
C:
题意:
给出两个01串,求(可将01串分割计算,两串对应长度必须相等)
它们(每次考虑2*len个数字)的最大MEX。
思路:
分情况讨论。
详情见代码。
题解:
#include <bits/stdc++.h>
#define bbn 200005
#define maxint 2147483647
#define maxLLint 9223372036854775807
#define mod 1000000007 //1e9+7
const double eps=1e-7;
typedef long long int LL;
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
string s,ss;
cin>>n;
cin>>s>>ss;
int sum=0;
for(int i=0; i<n; i++)
{
if(s[i]!=ss[i])
{
sum+=2;
continue;
}
if(s[i]==ss[i]&&s[i]=='1')
{
if(i+1<n&&s[i+1]==ss[i+1]&&s[i+1]=='0')
{
sum+=2;
i++;
continue;
}
}
if(s[i]==ss[i]&&s[i]=='0')
{
if(i+1<n&&s[i+1]==ss[i+1]&&s[i+1]=='1')
{
sum+=2;
i++;
continue;
}
else
{
sum++;
}
}
}
cout<<sum<<endl;
}
}
D1:
题意:
给出m个等级,等级越低,排的越靠前;等级越高,排的靠越后。但是入场顺序不能改变。
思路:
暴力。
在本位置后面遇见大于本位置数的,sum++。
题解:
#include <bits/stdc++.h>
#define bbn 200005
#define maxint 2147483647
#define maxLLint 9223372036854775807
#define mod 1000000007 //1e9+7
const double eps=1e-7;
typedef long long int LL;
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m;
cin>>n>>m;
int a[bbn]= {};
for(int i=1; i<=m; i++)
{
cin>>a[i];
}
int sum=0;
for(int i=1; i<=m; i++)
{
for(int j=i+1; j<=m; j++)
{
if(a[j]>a[i])
{
sum++;
}
}
}
cout<<sum<<endl;
}
}
补题篇:
D2:
题意:
给出n*m个等级,等级越低,排的越靠前;等级越高,排的靠越后。但是入场顺序不能改变。
思路:
等级已经决定了位置,能改变的只有等级相同的人的位置。
用堆储存等级与编号,优先级是等级大于编号。
先用sort排序,主要是排等级,决定等级位置;
编号取负,使:同等级大编号(取负前)先进场,降低sum,起优化作用。
然后一排一排的考虑,每次考虑m个。
每考虑m个,sort一下,主要是排编号。
即:等级相同时,取负前的大的编号在前面。
在m个数中,
判断方法1(标程判断方法):对每一个数,此数前面有小编号(取负前)的,sum++;
判断方法2(同D1暴力判断方法):对每一个数,此数后面有大编号(取负前)的,sum++;
题解:
#include <bits/stdc++.h>
#define bbn 200005
#define maxint 2147483647
#define maxLLint 9223372036854775807
#define mod 1000000007 //1e9+7
const double eps=1e-7;
typedef long long int LL;
using namespace std;
#define x first
#define y second
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m;
cin>>n>>m;
vector<pair<int,int>>a(n*m);
for(int i=0; i<=n*m-1; i++)
{
cin>>a[i].x;
a[i].y=i;
}
sort(a.begin(),a.end());
for(int i=0; i<n*m; i++)
{
a[i].y=-a[i].y;
}
int sum=0;
for(int i=0; i<n; i++)
{
sort(a.begin()+m*i,a.begin()+(i+1)*m);
/*
for(int j=0; j<m; j++)
{
for(int k=0; k<j; k++)
{
if(a[i*m+k].y>a[i*m+j].y)
{
sum++;
}
}
}
标程判断方法。
*/
for(int j=0; j<m; j++)
{
for(int k=j; k<m; k++)
{
if(a[i*m+j].y>a[i*m+k].y)
{
sum++;
}
}
}
}
cout<<sum<<endl;
}
}
总结:
第一次写这么多题,但好像加分不多。