wsyu24年暑假热身赛第2场题解

A

因为数组在循环位移的过程中,只有满足在非递减数组的情况下才记做一次排序,现在分两种情况来看

\(a\) 为排序后的数组名,\(0\) 为首个下标,\(n - 1\) 为最后一个下标。

  • \(a[0] < a[n - 1]\) 进行一次位移操作后 \(a[n - 1]\) 变成 \(a[n - 2]\), \(a[0]\)变成 \(a[n - 1]\), 这时候 \(a[n - 2] > a[n - 1]\) 排序不成立, 后续的排序也一定不成立,一共有能组成 \(1\) 种排列。
  • a[0] == a[n] 进行一次位移操作后 \(a[0]\) 变成 \(a[n]\) ,但数值并未发生改变,一共可以有 \(n\) 种排列。
#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

void solve() {
    int n, m;
    cin >> n >> m;
    if (m == 1) {
    	for (int i = 1; i <= n; i ++ ) {
    		cout << i << ' ';
    	}
    } else if (n == m) {
    	for (int i = 1; i <= n; i ++ ) {
    		cout << 1 << ' ';
    	}
    } else {
    	cout << -1;
    }
    cout << endl;

}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int tt = 1;
    cin >> tt;
    while (tt--) {
        solve();
    }
    
    return 0;
}

B

把一个数 \(x\)\(2^i\) 表示出来,可以看出这是一道将 \(x\) 转成二进制来计算的题,但由于题目要求连续的两个数必须要有一个为 \(0\), 现在的问题就变成了,如何将原本的多个\(1\)组成的字符串转换成\(-1\)\(0\)

以下由二进制表示:

(高位) 10011110
(高位) 1010000-10 连续的 \(1\) 可以变成以 $-1 $结尾,首地址前一位改为\(1\),中间为\(0\)的字符串。

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

void solve() {
    int n;
    cin >> n;
    vector<int> res;

    while (n) {
    	res.push_back(n & 1);
    	n >>= 1;
    }

    for (int i = 0; i < res.size(); i ++ ) {
    	if (res[i] == 1 && (i + 1 < res.size() && res[i + 1] == 1)) {
    		int j;
    		res[i] = -1;
    		for (j = i + 1; j < res.size() && res[j] == 1; j ++ ) {
    			res[j] = 0;
    		}
    		if (j == res.size()) res.push_back(1);
    		else res[j] = 1;
    		i = j - 1;
    	}
    }

    cout << res.size() << endl;
    for (int i = 0; i < res.size(); i ++ ) {
    	cout << res[i] << ' ';
    }
    cout << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int tt = 1;
    cin >> tt;
    while (tt--) {
        solve();
    }
    
    return 0;
}

C

因为没有次数限制,当 \(x > y\) 时所有的门一定会被全部破坏,反之只有小于等于\(x\)且没有被维修过的门才会被破坏。记录小于等于 \(x\) 的数量除 \(2\) ,由于是先破坏再修补所以是上取整。

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

int n, x, y;
int res;

int main() {
    cin >> n >> x >> y;
    for (int i = 0; i < n; i ++ ) {
        int t;
        cin >> t;
        if (t <= x) res ++ ;
    }

    if (x > y) cout << n << endl;
    else cout << (res + 1) / 2 << endl;

    return 0;
}

D

当字符为"^"时特判,如果当前符号位'_'且前面缺少'^'时需要补充,结尾如果不是'^'时计数增加1。

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

void solve() {
    string s;
    cin >> s;
    int res = 0;
    if (s == "^") {
    	cout << 1 << endl;
    	return;
    }

    for (int i = 0; i < s.size(); i ++ ) {
    	if ((i == 0 || s[i - 1] != '^') && s[i] == '_')
    		res ++ ;
    }
    if (s.back() == '_') res ++ ;

    cout << res << endl;

}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int tt = 1;
    cin >> tt;
    while (tt--) {
        solve();
    }
    
    return 0;
}

E

\(l != r\) 由于最小的非 \(1gcd\) 值是 \(2\) ,所以只要能组合成两个偶数就可以满足条件。

\(r - 1 >= l\)\(r - 2 > 0\) 即可

\(l == r\) 时寻找 \(l\) 的所有因子 \(x\), 当 \(gcd(x, l - x) != 1\)\((l - x != 0)\)时输出即可。

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

LL gcd(LL a, LL b) {
	return b ? gcd(b, a % b) : a;
}

void solve() {
    int l, r;
    cin >> l >> r;
    if (l == r) {
    	for (int i = 2; i <= sqrt(l); i ++ ) {
    		if (l % i == 0) { //只有l 和 l - i同时位质数时gcd为1, 但因为l是i的倍数,(l - i)要么等
    			cout << i << ' ' << l - i << endl; //于i,要么是i的倍数,他们的gcd值一定不为1。
	    		return;
    		}
    	}
    	cout << -1 << endl;
    } else {
    	if (r % 2) r -- ;
    	if (r - 2 > 0) {
    		cout << 2 << ' ' << r - 2 << endl;
    	} else {
    		cout << -1 << endl;
    	}
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int tt = 1;
    cin >> tt;
    while (tt--) {
        solve();
    }
    
    return 0;
}

F

统计不是第一次遇到的数字的个数,这就是要删掉的个数,由于一次删除两个数字,多余的操作在结果上减去即可(存在多余操作,一定会删掉非重复数字,使结果减少)。

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

void solve() {
    int n, res = 0;
    set<int> q;
    cin >> n;
    while (n -- ) {
    	int x;
    	cin >> x;
    	if (q.count(x)) res ++ ;
    	q.insert(x);
    }
    cout << q.size() - res % 2 << endl;

}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int tt = 1;
    cin >> tt;
    while (tt--) {
        solve();
    }
    
    return 0;
}
posted @ 2024-08-08 17:45  衫尘  阅读(37)  评论(0编辑  收藏  举报