Codeforces Round 981 (Div. 3)

链接:https://codeforces.com/contest/2033

A

A

Sakurako and Kosuke

大意:

        一个人跳1 5 9, 一个人跳 3 7 11,问谁能跳不超过x的最后一跳

思路:

        %4, 逐个分析

代码:

        

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define  vi vector<int>
#define  vii vector<pair<int, int>>
#define ff first 
#define ss second 
// ++   ~!    */+-    <<>>    <>  ==   &^|   &&|| =


void solve()
{
	int n;cin >> n;
	n %= 4;
	if (n == 0 || n == 2)cout << "Sakurako" << endl;
	else cout << "Kosuke" << endl;

}

signed main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int t = 1;
	cin >> t;
	while (t--) solve();

	return 0;
}
/*   /\_/\
*   (= ._.)
*   / >  \>
*/

B

B

Sakurako and Water

大意:

        对主对角线操作一次,对角线上元素加一,求使得所有元素非负的最小操作数

思路:

        求得主对角线元素最小值,为负就加上绝对值大小

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define  vi vector<int>
#define  vii vector<pair<int, int>>
#define ff first 
#define ss second 
// ++   ~!    */+-    <<>>    <>  ==   &^|   &&|| =


void solve()
{
	int n;cin >> n;
	vector<vi> g(n + 1, vi(n + 1));
	map<int, int> mp;
	for(int i = 1; i <= n; i ++)	
		for (int j = 1; j <= n; j++)
		{
			cin >> g[i][j];
			if (g[i][j] < 0)
			{
				mp[i - j] = min(mp[i - j], g[i][j]);
			}
		}
	int ans = 0;
	for (int i = -n + 1; i <= n - 1; i++)ans -= mp[i];
	cout << ans << endl;
}

signed main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int t = 1;
	cin >> t;
	while (t--) solve();

	return 0;
}
/*   /\_/\
*   (= ._.)
*   / >  \>
*/

C

C

Sakurako's Field Trip

大意:

        一堆数,每次可以移动一个数和对称的数,及 i 和 n + 1 - i, 求最少多少相邻的数相等

思路:

        两边由外到内,如果左边数跟左边相邻或者右边数跟右边相邻,交换一下(贪心,感觉这样最好,换或者不换,对外边而言一定不亏),然后记录一下,左右跟外边相邻的个数,最后奇偶讨论一下中间

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define  vi vector<int>
#define  vii vector<pair<int, int>>
#define ff first 
#define ss second 
// ++   ~!    */+-    <<>>    <>  ==   &^|   &&|| =


void solve()
{
	int n;cin >> n;
	vi v(n);
	for (int i = 0; i < n; i++)cin >> v[i];
	int cnt = 0;
	for (int i = 1; i < n / 2; i++)
	{
		if (v[i] == v[i - 1] || v[n - i - 1] == v[n - i])swap(v[i], v[n - i - 1]);
		if (v[i] == v[i - 1])cnt++;
		if (v[n - i - 1] == v[n - i])cnt++;
	}
	if (n & 1)
	{
		if (v[n / 2] == v[n / 2 - 1])cnt++;
		if (v[n / 2] == v[n / 2 + 1])cnt++;
	}
	else
	{
		if (v[n / 2] == v[n / 2 - 1])cnt++;
	}
	cout << cnt << 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

D

Kousuke's Assignment

大意:

        求最大不重叠的满足区间和等于0的区间数量

思路:

        从前往后读,与一个暂存量相加,用set存相加后的值,set里面默认插入一个0,然后每一次询问相加后的值是否在set里出现过,如果是就ans++,暂存量赋0,把set清空再插入个0

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define  vi vector<int>
#define  vii vector<pair<int, int>>
#define ff first 
#define ss second 
// ++   ~!    */+-    <<>>    <>  ==   &^|   &&|| =


void solve()
{
	int n;cin >> n;
	int sum = 0;
	set<int>s;
	s.insert(0);
	int ans = 0;
	while (n--)
	{
		int x;cin >> x;
		sum += x;
		if (s.count(sum))
		{
			ans++;
			sum = 0;
			s.clear();
			s.insert(0);
		}
		else s.insert(sum);
	}
	cout << ans << endl;
}

signed main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int t = 1;
	cin >> t;
	while (t--) solve();

	return 0;
}
/*   /\_/\
*   (= ._.)
*   / >  \>
*/

E

E

Sakurako, Kosuke, and the Permutation

大意:

        对于一个排列,求最少需要多少交换操作,使得最后的排列满足p[i] = i或者p[p[i]] = i

思路:

      一个排列内元素都在环中,环或大或小,p[i]=i环元素为1,p[p[i]]=i元素为2,依次类推。对于交换操作,可以用来改变环的大小,最大可以使得一个环内大小减去2。对此,我们依次遍历每一个环,求出每个环环内元素个数,然后依次求得最小删几次可以删得只剩下大小为1或2的环即可。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define  vi vector<int>
#define  vii vector<pair<int, int>>
#define ff first 
#define ss second 
// ++   ~!    */+-    <<>>    <>  ==   &^|   &&|| =


void solve()
{
    int n;
    cin >> n;
    vi a(n + 1);
    vector<bool> vis(n + 1, false);
    int num = 0;
    for (int i = 1; i <= n; i++)
        cin >> a[i];

    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        int num = 0;
        if (vis[i]) continue;
        int j = i;
        while (!vis[j])
        {
            vis[j] = true;
            num++;
            j = a[j];
        }
        ans += (num - 1) / 2;
    }
    cout << ans << "\n";
    return;
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) solve();

    return 0;
}
/*   /\_/\
*   (= ._.)
*   / >  \>
*/

F

F

Kosuke's Sloth

大意:

        求第n个可以被k整除的斐波那契数

思路:

        皮亚诺定理 here,斐波那契数列%k最多不超过6k个就会重复,又由一个公式

gcd(f[n],f[m]) = f[gcd(n,m)],令n = i,m=c1*i,则gcd(f[i],f[c1*i]) = f[i] ,f[k*i]) = c2*f[i] 即那么f[i]能被k整除,f[c1 * i]也能被k整除,那么第n个能被k整除的数就在n*i

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define  vi vector<int>
#define  vii vector<pair<int, int>>
#define ff first 
#define ss second 
// ++   ~!    */+-    <<>>    <>  ==   &^|   &&|| =


void solve()
{
	int n, k;cin >> n >> k;
	int a = 1, b = 1;
	n %= mod;
	vi f = {0, 1, 1};
	int i = 3;
	while (1)
	{
		f[i % 3] = (f[(i - 2) % 3] + f[(i - 1) % 3]) % k;
		if (!f[i % 3]) break;
		i++;
	}
	if (k == 1)i = 1;
	cout << i  % mod * n % mod << endl;
}

signed main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int t = 1;
	cin >> t;
	while (t--) solve();

	return 0;
}
/*   /\_/\
*   (= ._.)
*   / >  \>
*/

### Codeforces Round 927 Div. 3 比赛详情 Codeforces是一个面向全球程序员的比赛平台,定期举办不同级别的编程竞赛。Div. 3系列比赛专为评级较低的选手设计,旨在提供更简单的问题让新手能够参与并提升技能[^1]。 #### 参赛规则概述 这类赛事通常允许单人参加,在规定时间内解决尽可能多的问题来获得分数。评分机制基于解决问题的速度以及提交答案的成功率。比赛中可能会有预测试案例用于即时反馈,而最终得分取决于系统测试的结果。此外,还存在反作弊措施以确保公平竞争环境。 ### 题目解析:Moving Platforms (G) 在这道题中,给定一系列移动平台的位置和速度向量,询问某时刻这些平台是否会形成一条连续路径使得可以从最左端到达最右端。此问题涉及到几何学中的线段交集判断和平面直角坐标系内的相对运动分析。 为了处理这个问题,可以采用如下方法: - **输入数据结构化**:读取所有平台的数据,并将其存储在一个合适的数据结构里以便后续操作。 - **时间轴离散化**:考虑到浮点数精度误差可能导致计算错误,应该把整个过程划分成若干个小的时间间隔来进行模拟仿真。 - **碰撞检测算法实现**:编写函数用来判定任意两个矩形之间是否存在重叠区域;当发现新的连接关系时更新可达性矩阵。 - **连通分量查找技术应用**:利用图论知识快速求解当前状态下哪些节点属于同一个集合内——即能否通过其他成员间接相连。 最后输出结果前记得考虑边界条件! ```cpp // 假设已经定义好了必要的类和辅助功能... bool canReachEnd(vector<Platform>& platforms, double endTime){ // 初始化工作... for(double currentTime = startTime; currentTime <= endTime ;currentTime += deltaT){ updatePositions(platforms, currentTime); buildAdjacencyMatrix(platforms); if(isConnected(startNode,endNode)){ return true; } } return false; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值