专栏文章

「ALFR Round 3」B Swap & Delete

P11446题解参与者 2已保存评论 2

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
2 条
当前快照
1 份
快照标识符
@miqpubmq
此快照首次捕获于
2025/12/04 08:46
3 个月前
此快照最后确认于
2025/12/04 08:46
3 个月前
查看原文
有人看到这道题可能直接就懵逼了,但是说句实话,如果你看懂了样例你就会发现,这题它纯纯一个分类讨论啊!!!
根据样例,我们可以发现,一旦 aia_ia1a_1 或者 ana_n 相等,这组数据就只要两个操作:
  1. 如果 anaia_n\ne a_i,那就交换 ana_naia_i,否则交换 a1a_1aia_i
  2. 直接给整个序列删掉!(因为上一步已经使得 a1=ana_1=a_n 了)
但是,先别急着打!看数据:

数据范围

子任务分值限制
111010n3n\le 3
222020n10n\le 10
332020ai2a_i\le 2
441010保证所有 aia_i 相等
554040-
对于 100%100\% 的数据,1T51\le T \le 51n1051\le n\le 10^50ai1090\le a_i\le 10^9
子任务 44,保证所有 aia_i 都相等?!
于是,我们可以轻松地得到另一个东西:如果 a1a_1 本来就等于 ana_n,你就可以直接给整个序列删掉!
那为什么不能先判样例的情况再判上面那种情况呢?
先给大家造一组有毒的数据:
CPP
1 2 1 2 1
如果你要是先判样例的情况的话。。。你懂的hhh,虽然我没试探过这道题目的数据强度,但是你自己去可以试试。
然后我们还可以把上面那组数据改一下:
CPP
3 2 1 2 4
于是,我们得到下面的结论:
如果 ai=aja_i=a_j,我们就可以发现,我们需要 33 次操作就可以把整个序列删掉,be like:
CPP
第一步:2 3 1 2 4
第二步:2 3 1 4 2
第三步:(只有空气了,因为序列被删光了())
但是,但是,这样了还没结束!
因为,如果这 nn 个数字互不相等,怎么弄?
呃,可想而知,我们要。。。一个一个删。。。于是,这种情况就要 nn 次操作了。
综上,所有情况都被推导出来了。
然后就是,上代码!!!
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
const int A=1000000005;
int n,a[N];
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
		}
		if(a[1]==a[n])
		{
			cout<<1<<endl;//先判有没有 a[1]==a[n] 这种情况,避免发生类似 1 2 1 2 1 的数据把你卡了。
		}
		else
		{
			bool flag=1;
			for(int i=2;i<n;i++)
			{
				if(a[i]==a[1]||a[i]==a[n])
				{
					cout<<2<<endl;
					flag=0;
					break;
				}
			}//判样例的情况。
			if(flag)
			{
				bool flag2=1;
				for(int i=2;i<n;i++)
				{
					for(int j=i+1;j<n;j++)
					{
						if(a[i]==a[j])
						{
							cout<<3<<endl;
							flag2=0;
							break;
						}
					}
				}//再判上面的第三种情况。
				if(flag2)
				{
					cout<<n<<endl;
				}//如果都不满足,那就是剩下的那种情况,输出 n 就完了!
			}
		}
	}
	return 0;//完结撒花~~~
}

评论

2 条评论,欢迎与作者交流。

正在加载评论...