日常训练2025-1-15

日常训练2025-1-15

E. Sakurako, Kosuke, and the Permutation

rating:1400

https://codeforces.com/contest/2033/problem/E

思路(贪心)

模拟一下题目逻辑我们发现,所以简单排列都是经过1 2 3 4 5 ... n 这样的排列通过每个数只能跟其他位置的一个数有一次交换,或者不交换变来的,

代码

#include <bits/stdc++.h>

typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;

void solve(){
	int n, ans = 0;
	std::cin >> n;

	std::map<int, int> mp;
	std::vector<int> v(n+1);
	
	for (int i = 1; i <= n; i++){
		std::cin >> v[i];
		mp[v[i]] = i;
	}


	for (int i = 1; i <= n; i++){
		if (v[i] == i || v[v[i]] == i) continue;
		ans++;
		int s = v[i];
		int t = mp[i];
		std::swap(v[s], v[t]);
		mp[v[s]] = s;
		mp[v[t]] = t;
	}

	std::cout << ans << '\n';

}

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
	int t = 1, i;
	std::cin >> t;
	for (i = 0; i < t; i++){
		solve();
	}
	return 0;
}

B. Alice's Adventures in Permuting

rating:1400

https://codeforces.com/problemset/problem/2028/B

思路(等差数列)

没思路。

代码

#include <bits/stdc++.h>
#include <array> 
using namespace std;
#define int long long
const int N = 1e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define  vi vector<int>
#define  vvi vector<vector<int>>
#define  vii vector<pair<int, int>>
#define ff first 
#define ss second 
// ++   ~!    */+-    <<>>    <>  ==   &^|   &&|| =
 
 
 
void solve() 
{
    int n, b, c;cin >> n >> b >> c;
 
    if (b == 0)
    {
        if (c < n - 2)cout << -1 << endl;
        else if (c == n - 2)cout << n - 1 << endl;
        else if (c == n - 1)cout << n - 1 << endl;
        else cout << n << endl;
 
        return;
    }
 
    if (c > n - 1)cout << n << endl;
    else 
    {
        int num = (n - 1 - c) / b + 1; // 在0,n - 1范围内的数
        cout << n - num << endl;
    }
 
}
 
signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
 
    int t = 1;
    cin >> t;
    while (t--) solve();
 
    return 0;
}
/*   /\_/\
*   (= ._.)
*   / >  \>
*/

D. Satyam and Counting

rating:1400

https://codeforces.com/problemset/problem/2009/D

思路(平面几何)

简单的统计即可

代码

#include <bits/stdc++.h>

typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 2e5+5;

void solve(){
	int n;
	std::cin >> n;

	// std::vector<int> y0, y1;
	std::set<int> y0, y1;
	// std::vector x(N, std::vector<int>());
	std::map<int, std::vector<int> > xs;

	for (int i = 0; i < n; i++){
		int a, b;
		std::cin >> a >> b;
		xs[a].emplace_back(b);
		if (b == 1){
			y1.insert(a);
		}else{
			y0.insert(a);
		}
	}

	i64 ans = 0;
	for (auto [x, arry] : xs){
		if (arry.size() == 2){
			ans += y1.size() - 1;
			ans += y0.size() - 1;
		}
	}

	for (auto e : y0){
		if (y0.count(e+2) && y1.count(e+1)) ans++;
	}
	for (auto e : y1){
		if (y1.count(e+2) && y0.count(e+1)) ans++;
	}

	std::cout << ans << '\n';

}

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
	int t = 1, i;
	std::cin >> t;
	for (i = 0; i < t; i++){
		solve();
	}
	return 0;
}

Bitwise Balancing

rating:1400

思路(按位考虑)

非常版的一个题,一般的做法就是按位考虑,把所有可能的情况列出来,然后归纳就行。

评述

这类题比较考查归纳能力,代码2的做法比较具有普遍性,但是写起来麻烦。

代码1(找规律)

#include <bits/stdc++.h>

typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;

void solve(){
	i64 a = 0, b, c, d;	
	std::cin >> b >> c >> d;
	for (int i = 0; i < 64; i++){
		if ((b >> i & 1) == (d >> i & 1)) ;
		else if (1 - (c >> i & 1) == (d >> i & 1)) a |= (1LL << i);
		else{
			std::cout << "-1" << '\n';
			return;
		}
	}

	std::cout << a << '\n';
}

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
	int t = 1, i;
	std::cin >> t;
	for (i = 0; i < t; i++){
		solve();
	}
	return 0;
}	

代码2(位图模拟)

#include <bits/stdc++.h>

typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 64;

void solve(){
	i64 _b, _c, _d;
	std::cin >> _b >> _c >> _d;

	std::bitset<N> b(_b);
	std::bitset<N> c(_c);
	std::bitset<N> d(_d);
	std::bitset<N> a;

	bool flag = true;
	int dig = 0;
	for (int i = 0; i < N; i++){

		int dig_b = b[i];
		int dig_c = c[i];
		int dig_d = d[i];

		bool flag2 = false;

		for (int a_i = 0; a_i <= 1; a_i++){
			int or_d = a_i | dig_b;
			int and_d = a_i & dig_c;
			int diff = or_d - and_d;
			int tot = diff + dig;

			if (tot < dig_d) continue;
			if ((tot - dig_d) % 2 != 0) continue;

			int t = (tot - dig_d) / 2;

			if (t < 0 || t > 1) continue;

			if (a_i == 1) a.set(i);

			dig = t;

			flag2 = true;
			break;
		}

		if (!flag2){
			flag = false;
			break;
		}
	}

	if (dig) flag = false;

	if (flag){
		i64 ans = 0;
		for (int i = 0; i < N; i++){
			if (a[i]){
				ans |= (1LL << i);
			}
		}

		std::cout << ans << '\n';
	}else{
		std::cout << "-1\n";
	}
}

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
	int t = 1, i;
	std::cin >> t;
	for (i = 0; i < t; i++){
		solve();
	}
	return 0;
}

E. Photoshoot for Gorillas

rating:1400

https://codeforces.com/problemset/problem/2000/E

思路(二维差分)

我现在肯定是要把相对较高的猩猩放到被计算次数较多也就是中间的格子,具体计算多少次也要算出来,所以直接差分处理一下

评述

本题可做二维差分板子题。

代码

#include <bits/stdc++.h>

typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;

void solve(){
	int n, m, k;
	std::cin >> n >> m >> k;
	int w;
	std::cin >> w;
	std::vector<int> ws(w);
	for (int i = 0; i < w; i++) std::cin >> ws[i];

	std::vector g(n+2, std::vector<int>(m+2, 0));
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m; j++){
			int x2 = i + k - 1, y2 = j + k - 1;

			if (x2 > n || y2 > m) continue;

			g[i][j]++;
			g[i][y2+1]--;
			g[x2+1][j]--;
			g[x2+1][y2+1]++;
		}
	}

	std::priority_queue<i64> q;
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m;j ++){
			g[i][j] += g[i-1][j] + g[i][j-1] - g[i-1][j-1];
			q.push(g[i][j]);
		}
	}

	i64 ans = 0;
	std::sort(ws.begin(), ws.end());
	for (int i = w-1; i >= 0 && !q.empty(); i--){
		ans += q.top() * ws[i];
		q.pop();
	}

	std::cout << ans << '\n';
}

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
	int t = 1, i;
	std::cin >> t;
	for (i = 0; i < t; i++){
		solve();
	}
	return 0;
}

C - Sowing Stones

rating:绿色

https://atcoder.jp/contests/abc379/tasks/abc379_c

思路(贪心)

逻辑比较简单,就是一个类模拟过程。类模拟的意思是框架还是在模拟,只是对过程做了很多优化。

评述

一定要好好看题,不然辛辛苦苦写了20分钟,结果白忙活。

代码1

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

const int maxn = 2e6 + 5;
typedef long long ll;

pair<ll,ll> a[maxn];

void solve() {
	int n, m;
	cin >> m >> n; 
	ll tot = 0;
	for (int i = 1; i <= n; i++) cin >> a[i].first;
	for (int i = 1; i <= n; i++) cin >> a[i].second, tot += a[i].second;
	if (tot != m) {
		cout << "-1\n";
		return ;
	}
	sort(a + 1, a + 1 + n);

	long long now = m;
	long long ans = 0;
	for (int i = n; i >= 1; i--) {
		ll pos = a[i].first;
		ll num = min(now - pos + 1, a[i].second);

		
		//now - num + 1 - pos, now - pos
		ans += (now - num + 1 - pos + now - pos) * num / 2;
		// cout << now << " " << pos << " " << num << ' ' << ans <<  endl;
		now = now - num;
		// cout << now <<endl;
	}
	if (now == 0) cout << ans << endl;
	else cout << -1 << endl;
	
}

int main() {
	ios::sync_with_stdio(0);
	int T = 1;
	// cin >> T;
	while (T--) solve();
}

代码2

#include <bits/stdc++.h>

typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;

void solve(){
	i64 m, n, tot = 0;
	std::cin >> m >> n;

	std::vector<pll> a(n+1);

	for (int i = 1; i <= n; i++) std::cin >> a[i].first;
	for (int i = 1; i <= n; i++) std::cin >> a[i].second, tot += a[i].second;

	std::sort(a.begin(), a.end());
	if (tot != m){
		std::cout << "-1\n";
		return;
	}

	i64 now = 0;
	for (int i = n; i >= 1; i--){
		now += a[i].second;
		if (m - a[i].first + 1 < now){
			std::cout << "-1\n";
			return;
		}
	}

	i64 ans = m * (m + 1) / 2;
	for (int i = 1; i <= n; i++){
		ans -= a[i].first * a[i].second;
	}

	std::cout << ans << '\n';

}

signed main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
	int t = 1, i;
	for (i = 0; i < t; i++){
		solve();
	}
	return 0;
}
posted @ 2025-01-15 11:16  califeee  阅读(25)  评论(0)    收藏  举报