1 条题解

  • 0
    @ 2026-5-4 22:22:12

    解题思路

    首先,统计数组中每个元素出现的次数,保存在数组 cntcnt 中。由于元素的最大可能值为 2×1052 \times 10^5,我们可以直接用一个大小为 2×105+12 \times 10^5 + 1 的数组来统计,无需使用复杂的数据结构。

    然后检查是否存在某个 ii0i2×1050 \le i \le 2 \times 10^5)使得 cnti>2cnt_i > 2。如果存在,则输出 "NO",因为该元素至少需要在其中一个序列中出现两次,但一个序列中不能有重复的严格递增或严格递减元素(除非是同一个值在递增和递减序列中各出现一次,但这样总数最多为 22),出现超过 22 次是不可能的。

    接下来构造递增序列:递增序列中的元素个数等于满足 cnti=2cnt_i = 2 的元素个数。我们从左到右遍历,输出这些元素,每输出一个就将其 cntcnt11(即从计数中移除一个)。

    递减序列中的元素个数即为剩余所有 cnti0cnt_i \neq 0 的元素数量。我们从右到左遍历,输出这些元素即可。


    C++ 代码实现

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int main() {
    #ifdef _DEBUG
    	freopen("input.txt", "r", stdin);
    //	freopen("output.txt", "w", stdout);
    #endif
    	
    	int n;
    	cin >> n;
    	vector<int> cnt(200 * 1000 + 1);
    	for (int i = 0; i < n; ++i) {
    		int x;
    		cin >> x;
    		++cnt[x];
    		if (cnt[x] > 2) {
    			cout << "NO" << endl;
    			return 0;
    		}
    	}
    	
    	cout << "YES" << endl << count(cnt.begin(), cnt.end(), 2) << endl;
    	for (int i = 0; i <= 200 * 1000; ++i) {
    		if (cnt[i] == 2) {
    			cout << i << " ";
    			--cnt[i];
    		}
    	}
    	cout << endl << count(cnt.begin(), cnt.end(), 1) << endl;
    	for (int i = 200 * 1000; i >= 0; --i) {
    		if (cnt[i] == 1) {
    			cout << i << " ";
    			--cnt[i];
    		}
    	}
    	cout << endl;
    	
    	assert(count(cnt.begin(), cnt.end(), 0) == 200 * 1000 + 1);
    	
    	return 0;
    }
    
    • 1

    信息

    ID
    6858
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者