错误点:一开始想的太复杂,一直在考虑整体情况。
只需要直接考虑第一步即可。
以下所有【】代表坐标,从1开始,()代表数值
因为取偶数段,所以第二段的开始位置为【2,n - k + 2】,要尽可能的小,那么我们就让第一个数不是1,假设数组为1 1 1 1 3 1 2 1,那么如果4在【2,n - k + 2】,我就让第一段为前四个(1,1,1,1),那么第一个数就为3,答案最小。
所以只要【2,n - k + 2】这段范围有一个不是1,答案就为1。
else:【2,n - k + 2】这段范围全是1:
如果说n==k,那么每段为1,结果为1 ,正常模拟即可。
如果n ! = k,那么n - k + 2 >= 3,那么我就让第二段为【2,3】,那么第一段为(1,1),答案等于2。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int a[N];
void solve()
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
if(n==k)
{
int ans=0;
for(int i=2;i<=n;i+=2)
{
if(a[i]!=ans+1) break;
ans++;
}
cout<<ans+1<<'\n';
return ;
}
bool st=1;
for(int i=2;i<=n-k+2;i++)
if(a[i]!=1) st=0;
cout<<st+1<<'\n';
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int T=1;
cin>>T;
while(T--)
solve();
return 0;
}
把题目意思转化过来每一行的后缀和组成MEX,求max
最重要的是发现 ai,j >=1,那么想要n个数的后缀和=n,只能每个数都为1。如果ans=3,那么就需要有(0,1,2), 0是肯定有的。1就需要在倒数第二个阶段服务那它,2就需要在倒数第三个阶段服务那它,且这两个的后缀1的个数分别>=1 , >=2。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=310;
int mm[N][N];
void solve()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>mm[i][j];
vector<int> v;
int mx=-1;
for(int i=0;i<n;i++)
{
int num=0;
for(int j=n-1;j>=0;j--)
{
if(mm[i][j]!=1) break;
num++;
}
mx=max(mx,num);
v.push_back(num);
}
sort(v.begin(),v.end());
int now=0;
for(int i=0;i<n;i++)
{
while(i<n&&v[i]<now) i++;
if(i>=n) break;
now++;
}
cout<<now<<'\n';
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int T=1;
cin>>T;
while(T--)
solve();
return 0;
}