• CF653C Solution


    题目链接

    题解

    下文将不符合条件的序列元素称为“劣元素”。

    可以发现,交换两数\(t_i,t_j\)最多只可影响到\(\{t_{i-1},t_i,t_{i+1},t_{j-1},t_j,t_{j+1}\}6\)个序列中元素。因此我们可以找出所有劣元素,如果其个数\(>6\)则判断无法实现。

    因为\(t_{2k+1}>t_{2k}\)\(t_{2k+1}>t_{2k+2}\)此类劣元素一定是成对出现且互相影响的,只有将劣元素与其他元素互换才会对序列状态产生影响。因此我们可以枚举劣元素与其他元素,将其互换后判断当前序列是否合法。因为经过先前特判劣元素个数\(\le 6\),而判断序列是否合法只需判断所有劣元素与互换的元素是否合法即可,时间复杂度为\(O(36n)\)

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=15e4+10,inf=0x3f3f3f3f;
    int t[N],wr[N];//wr:劣元素
    bool w[N];//w[i]:下标为i的元素是/否(1/0)为劣元素
    bool check(int x)//下标为x的元素是否合法
    	{return (x%2 && t[x]<t[x-1] && t[x]<t[x+1]) || (x%2==0 && t[x]>t[x-1] && t[x]>t[x+1]);}
    int main()
    {
    	int n,cnt=0,ans=0;//cnt:劣元素个数
    	scanf("%d",&n);	
    	for(int i=1;i<=n;i++) scanf("%d",&t[i]);
    	t[0]=inf;
        //为使t[1]可以被check判断合法,需保证t[0]>a[1]
    	if(n%2) t[n+1]=inf;
        //为使t[n]可以被check判断合法,需保证当n为偶数时t[n+1]<t[n],奇数时t[n+1]>t[n]
    	for(int i=1;i<=n;i++) 
    		if(!check(i)) {wr[++cnt]=i; w[i]=1;}
    	if(cnt>6) {printf("0"); return 0;}
    	for(int i=1;i<=cnt;i++)
    	{
    		for(int j=1;j<=n;j++)
    		{
    			if(w[j] && j<=wr[i]) continue;
    			swap(t[wr[i]],t[j]);
    			bool flag=check(j);
    			for(int k=1;k<=cnt;k++) flag&=check(wr[k]);
    			swap(t[wr[i]],t[j]); ans+=flag; 
                //为使接下来的判断不受影响,需抹消互换操作
    		}
    	}
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    019_Mac实用的图像备份工具
    016_把普通用户免秘钥加入root用户的几种方式
    027_磁盘维护命令du等
    026_lsof命令经验总结
    004_wireshark专题
    029_mount bind挂载
    023_nginx跨域问题
    mysql-5.7 group commit 详解
    二段式提交协议
    mysql-5.7 密码过期详解
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14388848.html
Copyright © 2020-2023  润新知