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;
}