Codeforces Round 926 (Div. 2) 赛后总结

这场比赛掉了前三场比赛上的分,望周知。


Sasha and the Beautiful Array
题目大意:一个有n个数的数组,对n个数进行排序,求数组中 ai-ai-1 (下标从2到n)的和的最大值。
分析
列出来和式,为an-an-1+an-1-an-2……-a1
最后得到an-a1
那么an最大,a1最小即可。
很容易想到排序。

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 200010;
int a[N];

int main() {
	int _;
	cin >> _;
	while (_--) {
		int n;
		cin >> n;
		for (int i = 1; i <= n; i++) {
			cin >> a[i];
		}
		sort(a + 1, a + 1 + n);
		cout << a[n] - a[1] << endl;
	}
	return 0;
}

Sasha and the Drawing
题目大意:现有一个n*n的正方形单元格,此单元格最多有(4*n-2)条对角线,现给出n,并要求其中k条对角线,要求每条对角线上都要有一个涂色的小方格,求最少多少个涂色方格。
分析
这题纯纯一个脑筋急转弯,我尝试了多种思考方式,发现最靠谱的思考方式是这样的。
要求方格数最少,而对角线数是指定的,那么我们就要求每个涂色方格能占用最多的对角线。
每个方格有两条对角线,而当一个涂色方格占用了其中两条,那么有几个方格就只有一条对角线了,
按照我们的贪心策略,我们得尽最大的努力防止其只占用一条对角线,最好占用两条。
从最简单的情况进行思考,先在第一行和最后一行进行涂色是最容易讨论的。

首先,如果把第一行涂完了,那么最后一行就会有两个方格(最左边和最右边的)只有一条对角线,这是我们极力避免的。
那么我们只在第一行涂(n-1)个(剩下一个不涂,随便哪个都行,只要是第一行的就行),嗯,这样确实最后一行只有一个格子才有一条对角线,
再贪心一点,我们第一行只涂(n-2)个(最左边和最右边不涂),这样最后一行,全是两条对角线,
现在如果我们要把最后一行涂上,涂了n个,发现第一行那两个没涂色的格子只有一条对角线了。
那么现在,很容易可以想到,无论怎么涂,如果要涂(n+n-2)以上个格子,必有两个格子只有一条对角线,
而且如果用贪心策略涂了n+n个格子,那么整个单元格就没有对角线可涂了,全部都占用完了。
那么我们现在就可以得出答案,前(n+n-2)个格子可以占用其数量的2倍的对角线,剩下两个格子只占用1条对角线。
现在我们就可以写程序了。
PS.题目中的数据范围n>=2,但实际上如果没有讨论n=1的情况,会在 test3 wa,至少我是的,wa了几次,人都傻了。

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 200010;
int a[N];
typedef long long ll;

int main() {
	int _;
	cin >> _;
	while (_--) {
		ll n, k;

		cin >> n >> k;
		ll t = (n + n - 2) * 2;//4*n-4
		if (n == 1) {
			cout << 1 << endl;
			continue;
		}
		if (k <= t) {
			cout << (ll)ceil(k / 2.0) << endl;
		} else {
			ll tt = t / 2 + 1;
			if (k >= 4 * n - 2)
				tt++;
			cout << (ll)tt << endl;
		}
	}
	return 0;
}

Sasha and the Casino
题目大意:有一个前人去赌博,而赌场可以控制输赢,但他有一个bug,就是不可能连输x次,如果赢了,回报k倍的投注,现在有本金a,问是否有可能稳赚不赔。
分析
既然赌场可以控制输赢,但自己不会连输,那么就可以考虑这样一个策略,每一回合投注一定的钱,保证这一回合如果赢了就能获得比前几把输的还多的钱,
因为只要本金满足条件,总会有赢的时候,把输的全部赢回来就好了,而且还要赢额外的钱。
这就类似于现实中的倍投法,只要赢了,必定血赚

#include <iostream>
using namespace std;

int main() {
	int T;
	cin >> T;
	while (T--) {
		int k, x, a;
		cin >> k >> x >> a;
		int w = 1, sum = 0;
		for(int i=0;i<=x;i++)
		{
			w=sum/(k-1)+1;// 因为赢了就会赚w*(k-1) (赢钱本身也要投钱,所以是k-1),
                          //所以如果要稳赚,就要 w*(k-1)>sum。又因为程序向下取整,并且获得的钱一定要超过投入的钱,不能持平,所以+1
			sum+=w;//投入
            if(sum > a){
			cout<<"NO"<<endl;
            goto out;
		    }
		}
		cout<<"YES"<<endl;
        out:
        continue;
	}
	return 0;
}

重生之太菜了不会写另外三题/(ㄒoㄒ)/~~

posted @ 2024-02-16 13:41  STA_running  阅读(40)  评论(0)    收藏  举报