codeforces 2.0

1. Magnitude (Easy Version)

思路:

这里我们可以声明两个变量 l和r,从左向右遍历

1.如果l>=0,l就累加这个数

2.如果l<0,就让r加上这个数,此时如果r<0就让l加上这个r,r重新赋值为0,此时l仍然为负数

3.如果l<0,就让r加上这个数,此时如果r>0,保留r不变,继续往后遍历。

最后我们得到两种可能:

1.l>=0,r=0。这种情况下答案就是l

2.l<0 r>=0。这种情况下答案就是abs(l)+r

cpp 复制代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<cmath>
#include<map>
#include<set>
#define int long long
using namespace std;
void solve() {
	int n;
	cin >> n;
	vector<int>nums(n);
	for (int i = 0; i < n; i++) {
		cin >> nums[i];
	}
	int l = 0;
	int r = 0;
	for (int i = 0; i < n; i++) {
		if (l >= 0) {
			l += nums[i];
		}
		else if (l < 0) {
			r += nums[i];
			if (r < 0) {
				l += r;
				r = 0;
			}
			else if (r >= 0) {
				continue;
			}
		}
		
	}
	if (l < 0) {
		l = abs(l);
	}
	cout << l + r << endl;
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t; cin >> t;
	while (t--)solve();
	return 0;
}

2.Have Your Cake and Eat It Too

思路:

对给定的三个数组分别使用前缀和,枚举三人l和r的先后顺序(共六种)分别判断是否符合条件,若符合条件则输出。

代码:

cpp 复制代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<cmath>
#include<map>
#include<set>
#define int long long
using namespace std;
int n;
int target;
typedef struct place {
	int l;
	int r;
}p;
bool deal_sum(vector<int>a, vector<int>b, vector<int>c,int num1,int num2,int num3) {
	int i = 1;
	while (a[i] < target) {
		i++;
		if (i == n-1) {
			return false;
		}
	}
	int marka = i;
	while (b[i] - b[marka] < target) {
		i++;
		if (i == n)return false;
	}
	int markb = i;
	if (c[n] - c[markb] < target) {
		return false;
	}
	p x[4];
	x[num1].l = 1;
	x[num1].r = marka;
	x[num2].l = marka + 1;
	x[num2].r = markb;
	x[num3].l = markb + 1;
	x[num3].r = n;
	for (int i = 1; i <= 3; i++) {
		cout << x[i].l << ' ' << x[i].r << ' ';
	}
	cout << endl;
	return true;
	
}
void solve() {
	
	cin >> n;
	vector<int>suma(n + 1);
	vector<int>sumb(n + 1);
	vector<int>sumc(n + 1);
	for (int i = 1; i <= n; i++) {
		int a; cin >> a;
		suma[i] = suma[i - 1] + a;
	}
	if (suma[n] % 3 == 0) {
		target = suma[n] / 3;
	}
	else {
		target = suma[n] / 3 + 1;
	}
	for (int i = 1; i <= n; i++) {
		int b; cin >> b;
		sumb[i] = sumb[i - 1] + b;
	}
	for (int i = 1; i <= n; i++) {
		int c; cin >> c;
		sumc[i] = sumc[i - 1] + c;
	}
	
	if (deal_sum(suma, sumb, sumc,1,2,3))return;
	if (deal_sum(suma, sumc, sumb,1,3,2))return;
	if (deal_sum(sumb, suma, sumc,2,1,3))return;
	if (deal_sum(sumb, sumc, suma,2,3,1))return;
	if (deal_sum(sumc, suma, sumb,3,1,2))return;
	if (deal_sum(sumc, sumb, suma,3,2,1))return;
	cout << -1 << endl;
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t; cin >> t;
	while (t--)solve();
	return 0;
}

3.GCD-sequence

思路:

先算出原始的b数组(gcd之后的数组),然后从左向右遍历找出第一个b[i]>b[i+1]的位置i,这时出问题的值可能有三个a[i],a[i+1],a[i+2],依次去掉这三个值,获得去掉该值后的三个b数组,若三个数组存在一个非减数组,则输出"YES",如果不存在,输出"NO"。

代码:

cpp 复制代码
#include<iostream>
#include<vector>
#include<algorithm>
#define int long long
using namespace std;
int gcd(int a, int b) {
    return b ? gcd(b, a % b) : a;
}
void solve() {
    int n;
    cin >> n;
    vector<int>nums(n);
    for (int i = 0; i < n; i++) {
        cin >> nums[i];
    }
    if (n == 1) {
        cout << "YES" << endl;
        return;
    }
    vector<int>b(n - 1);
    for (int i = 0; i < n - 1; i++) {
        b[i] = gcd(nums[i], nums[i + 1]);
    }
    int mark = -1;
    for (int i = 0; i < n - 2; i++) {
        if (b[i] > b[i + 1]) {
            mark = i;
            break;
        }
    }
    if (mark == -1) {
        cout << "YES" << endl;
        return;
    }
    for (int j = 0; j < 3; j++) {
        int del_pos = mark + j; 
        if (del_pos >= n) break;
        vector<int>temp;
        for (int i = 0; i < n; i++) {
            if (i != del_pos) {
                temp.push_back(nums[i]);
            }
        }
        vector<int>btemp(n - 2);
        int flag = 0;
        for (int i = 0; i < n - 2; i++) {
            btemp[i] = gcd(temp[i], temp[i + 1]);
            if (i > 0 && btemp[i - 1] > btemp[i]) {
                flag = 1;
                break;
            }
        }
        if (flag == 0) {
            cout << "YES" << endl;
            return;
        }
    }
    cout << "NO" << endl;
}
signed main() {
    int t; cin >> t;
    while (t--)solve();
    return 0;
}

4.Final Boss

思路:

来自题解。利用set存入结构体pair,,结构体中的第一个变量代表第几个回合,第二个变量代表第几个技能,set首先按照结构体第一个变量大小排序,若第一个值大小相等,则按照第二个排序,具体思路见代码注释。

代码:

cpp 复制代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
#define int long long
void solve() {
	int h, n;
	cin >> h >> n;
	vector<int>a(n);
	vector<int>c(n);
	for (int i = 0; i < n; i++)cin >> a[i];
	for (int i = 0; i < n; i++)cin >> c[i];
	set<pair<int, int>>s;
	for (int i = 0; i < n; i++) {
		s.insert({ 1,i });
	}//初始化s,在第一个回合里,所有技能均可使用
	int turn = 1;//turn代表当前回合数
	while (h > 0) {
	    turn = s.begin()->first;
		int i = s.begin()->second;//这里从s中取出第一个元素,该元素在所有元素中turn最小
		h -= a[i];//对boss造成伤害
		s.insert({ turn + c[i],i });//下一次若想使用该技能需要在第turn+c[i]回合中
		s.erase(*s.begin());//该技能在该回合使用完毕,可以删除。
	}
	cout << turn << endl;
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int t; cin >> t;
	while (t--)solve();
	return 0;
}

5.Swap Dilemma

思路:

一步距离无论是多少的交换,都等同于奇数 次距离为2交换,这时假设a的数组不变,所以可以直接找把b数组交换为a数组时,一共需要多少步,不管这一步的距离是多少都是奇数次距离为2的交换,如果是偶数,则可以实现

为什么是偶数就可以实现?当总需求的 "等效次数" 为偶数时,能通过合理组合这些操作(或抵消多余步骤),实现数组的转换。

代码:

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#define int long long
using namespace std;
void solve() {
	int n; cin >> n;
	vector<int>a(n+1);
	vector<int>b(n+1);
	map<int, int>mp;
	for (int i = 1; i <= n; i++)cin >> a[i];
	for (int i = 1; i <= n; i++) {
		cin >> b[i];
		mp[b[i]] = i;
	}
	int ans = 0;
	for (int i = 1; i <= n; i++) {
		if (b[i] == a[i]) {
			continue;
		}
		if (mp[a[i]] == 0) {
			cout << "NO" << endl;
			return;
		}
		int x = mp[a[i]];
		swap(b[i], b[x]);
		mp[b[i]] = i;
		mp[b[x]] = x;
		ans++;
	}
	if (ans % 2 == 0) {
		cout << "YES" << endl;
		return;
	}
	cout << "NO" << endl;
}
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int t; cin >> t;
	while (t--)solve();
	return 0;
}
相关推荐
未知陨落3 小时前
LeetCode:98.颜色分类
算法·leetcode
~kiss~4 小时前
K-means损失函数-收敛证明
算法·机器学习·kmeans
杨小码不BUG4 小时前
Davor的北极探险资金筹集:数学建模与算法优化(洛谷P4956)
c++·算法·数学建模·信奥赛·csp-j/s
mit6.8244 小时前
10.5 数位dp
c++·算法
2401_881244405 小时前
P3808 AC 自动机(简单版)
算法
Jayden_Ruan6 小时前
C++十进制转二进制
数据结构·c++·算法
Haooog6 小时前
98.验证二叉搜索树(二叉树算法题)
java·数据结构·算法·leetcode·二叉树
Macre Aegir Thrym7 小时前
MINIST——SVM
算法·机器学习·支持向量机
Young_Zn_Cu8 小时前
LeetCode刷题记录(持续更新中)
算法·leetcode