A 统计之后补x个空就可以了,最大应该是max(ai)+x<=200;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
#define IOS ios::sync_with_stdio(0);
const int N=1000010;
int n,x,a[N],t,num[N];
int main()
{
cin>>t;
while(t--)
{
memset(num,0,sizeof num);
cin>>n>>x;
for(int i=0;i<n;i++) cin>>a[i],num[a[i]]++;
int cnt=0;
for(int i=1;i<=220;i++)
if(!num[i])
{
cnt++;
if(cnt>x)
{
cout<<i-1<<endl;
break;
}
}
}
return 0;
}
B 将一个数组分成两部分,两部分都是从1开始的全排列,一组数是全排列的话和就等于(1+l)*l/2(l是长度),而且还要不重复。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
#define IOS ios::sync_with_stdio(0);
const int N=200010;
int n,x,a[N],t,num[N];
ll sum[N];
bool stl[N],str[N];//stl左半部分是否有重复元素,str右半部分是否有重复元素
int main()
{
cin>>t;
while(t--)
{
vector<PII> ve;
cin>>n;
stl[0]=1;
for(int i=1;i<=n;i++) num[i]=0;//清零,用memset应该会超时
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum[i]=sum[i-1]+a[i];
if(stl[i-1]==1)
{
if(num[a[i]]) stl[i]=0;
else num[a[i]]++,stl[i]=1;
}
else stl[i]=0;
}
for(int i=1;i<=n;i++) num[i]=0;
for(int i=n;i;i--)
{
if(i==n||str[i+1]==1)
{
if(num[a[i]]) str[i]=0;
else num[a[i]]++,str[i]=1;
}
else str[i]=0;
}
for(int i=1;i<n;i++)
{
int l=n-i;
if(sum[i]==1ll*(i+1)*i/2&&(sum[n]-sum[i])==1ll*(l+1)*l/2&&stl[i]&&str[i+1])
ve.push_back({i,l});
}
cout<<ve.size()<<endl;
for(int i=0;i<ve.size();i++)
cout<<ve[i].first<<' '<<ve[i].second<<endl;
}
return 0;
}
补题:
C 每个li可以选择区间[1,n-li+1]内的一个数为起点给长度为li的区间染色,每次颜色各不相同,问是否可以染色m次后区间[1,n]全被染色而且有m种不同颜色,就是每种颜色都没有被完全覆盖。
n-li+1+li-1==n,就是说每种颜色都是可以染到n的,那么考虑将后面的颜色首尾相连去染色,求一个sumi,就是后i中颜色最多可以染多少格,然后先将前面的颜色每次染色后只剩下一个格子,直到后面的不足以把剩下的全覆盖就跳出,后面的就尽量多的染色,但是不能将前面的格子覆盖就要大于前一个染色的点,最后判断染色后能不能将n个格子全部染上色,就是相邻的染色区有没有交集,还有每次染色的点(染色区间左端点就是输出的那个值)不能大于n-li+1;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
#define IOS ios::sync_with_stdio(0);
const int N=200010;
int n,m,a[N],t;
ll b[N],num[N];
ll sum[N];
bool stl[N],str[N];
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
cin>>a[i];
for(int i=m;i;i--) sum[i]=sum[i+1]+a[i];
int l=m+1;
for(int i=1;i<=m;i++)//先每次只染一个格子
{
if(sum[i+1]+i>=n) b[i]=i;
else //剩下的不能全部染上色就跳出
{
l=i;
break;
}
}
for(int i=l;i<=m;i++)//剩下的尽量多的格子
b[i]=max(b[i-1]+1,n-sum[i+1]-a[i]+1);
bool flag=1;
b[0]=1;
for(int i=1;i<=m;i++)
if(b[i-1]+a[i-1]<b[i]||b[i]>n-a[i]+1) flag=0;
if(flag)
for(int i=1;i<=m;i++) cout<<b[i]<<' ';
else cout<<-1;
return 0;
}