1 条题解

  • 0
    @ 2025-8-24 21:25:20

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Pisces
    AFO || QwQ

    搬运于2025-08-24 21:25:19,当前版本为作者最后更新于2018-08-09 22:39:29,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    一篇很水的题解

    方法解释:找到它的原结果和目标结果,并作差:

    原:2 3 1 1

    目标:1 1 2 3

    差:1 2 -1 -2

    此时要交换两个数只需要对差进行改变,如将2和第一个1交换,2的差减1,1的差加1,就都变成0了,最后只需要把差全部变为0即可。

    样例解释:

    编号:1 2 3 4 5 6 7 8 9

    原:2 2 1 3 3 3 2 3 1

    目标:1 1 2 2 2 3 3 3 3 //因为要从小到大排

    差:1 1 -1 1 1 0 -1 0 -2

    将1和3对调,差变为0和0,将2和7对调,差变为0和0,将4和9对调,差变为0和-1,将5和9对调,差变为0和0,共4步。

    因此,因尽量使它们‘差’的和尽量接近0,所以就有一种奇特的方法:

    统计差为1的个数,这些ans都要+1的,再统计差为2的个数,如果有-2对应ans就+1,没有对应就+2。

    下面上代码(在洛谷上过不了,所以别想抄题解,但把数据下下来发现答案都是正确的,在别的oj上也能过):

    #include<bits/stdc++.h>
    #define f(i,a,b) for(register int i=a;i<=b;++i)
    using namespace std;
    int p,s,tot,ans,have,q,m;
    char a[1005<<1],b;//会读入换行,数组大小要*2
    int main()
    {
        cin>>m;
        f(i,1,m<<1){//读入
        	if(isdigit(b=getchar())){//判断是否为换行
        		a[++p]=b;//存入
        		if(b=='1'){//无需打排序,直接操作
        			int k=a[++s]=='3';//判断是否为3,如果是3,则差为2
        			ans+=a[s]=='2'+k;//先全部+1,再单独判断有没有对应
        			have+=k;//统计差为2的个数
        		}
        		else tot+=b=='2';//统计2的个数
            } 
        }
        f(i,s+1,s+tot){//目标结果为2的部分
            ans+=a[i]=='3';//统计差为1的个数
        }
        f(i,s+tot+1,p){//目标结果为3的部分
            q+=a[i]=='1';//统计差为-2的个数
        }
        cout<<ans+((have>q)?have-q:0)<<endl;//把没有-2对应的2的部分加上
        return 0;
    }
    

    本人(蒟蒻)第一次发题解,但好像时间复杂度好像还蛮低的

    • 1

    [USACO2.1] 三值的排序 Sorting a Three-Valued Sequence

    信息

    ID
    453
    时间
    1000ms
    内存
    125MiB
    难度
    2
    标签
    递交数
    0
    已通过
    0
    上传者