2021-07-25

暑假集训第五篇博客
2021年四川省赛
A.Chuanpai
题意:本题给你一个整数k, 问你在x ∈[1,6] 和 y∈[1,6]能找到多少对x 和 y,其中(x,y)
和(y,x)算一对。
思路:按照x和y的范围暴力枚举就好,当时记得这题出来的很慢,因为没有看到范围,下次要注意,看完整题目中的条件。
代码:

#include <bits/stdc++.h>

using namespace std;

int k;
int main()
{
	int t;
	cin >> t;
	while(t -- )
	{
		cin >> k;
		int ans = 0;
		for(int i = 1; i <= 6; i ++ ){
			for(int j = i; j <= 6; j ++ )
			{
				if(i + j  == k) ans ++;
			}
		}
		//cout << "!!!!!";
		cout << ans << endl;
	}
	return 0;
}

D.Rock Paper Scissors
题意:博弈论。Dream和Bob玩手头剪刀布,谁赢谁就得一分,谁输就扣一分,平局得分保持不变他们的所有得分和扣分算在一起,假设它为sum,Bob想最小化sum,而Dream想最大化总分sum,每个人都都会以最可能的赢的策略出牌,Rock先出,题目会给你Dream和Bob的石头剪刀布的个数,你要算出最后的得分。
思路:本题思路就是,因为Bob先出,所以由Dream掌握一切,Dream肯定以这样的策略出牌:Rock出什么他尽可能的出能赢他的牌,若没有则出相同的牌,最后没有办法了就出输的牌。
代码(我的一种一种情况讨论的,所以代码比较烦,调试也调了很长时间)

#include <bits/stdc++.h>

using namespace std;

long long b1, b2, b3, d1, d2, d3, t;

int main()
{
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin >> t;
	while(t -- )
	{
		cin >> b1 >> b2 >> b3 >> d1 >> d2 >> d3;
		long long ans = 0;
		if(b1 <= d2)
		{
			ans += b1;
			d2 -= b1;
			b1 = 0;
			if(b2 <= d3)
			{
				ans += b2;
				d3 -= b2;
				b2 = 0;
				if(b3 <= d1)
				{
					ans += b3;
					d1 -= b3;
					b3 = 0;
				}
				else if(b3 > d1)
				{
					ans += d1;
					b3 -= d1;
					d1 = 0;
				}
			}
			else if(b2 > d3)
			{
				ans += d3;
				b2 -= d3;
				d3 = 0;
				if(b3 <= d1)
				{
					ans += b3;
					d1 -= b3;
					b3 = 0;
				}
				if(b3 > d1)
				{
					ans += d1;
					b3 -= d1;
					d1 = 0;
				}				
			}
			
		}
		else if(b1 > d2)
		{
			ans += d2;
			b1 -= d2;
			d2 = 0;
			if(b2 <= d3)
			{
				ans += b2;
				d3 -= b2;
				b2 = 0;
				if(b3 <= d1)
				{
					ans += b3;
					d1 -= b3;
					b3 = 0;
				}
				else if(b3 > d1)
				{
					ans += d1;
					b3 -= d1;
					d1 = 0;
				}
			}
			else if(b2 > d3)
			{
				ans += d3;
				b2 -= d3;
				d3 = 0;
				// cout << "!!!!!" << b2 << endl;
				if(b3 <= d1)
				{
					ans += b3;
					d1 -= b3;
					b3 = 0;
				}
				else if(b3 > d1)
				{
					ans += d1;
					b3 -= d1;
					d1 = 0;
				}				
			}			
		}
		// cout << b1 << " " << b2 << " " << " " << b3 << " " << d1 << " " << d2 << " " << d3 << " " << endl;
		long long aa = d1, bb = d2, cc = d3;
		d1 = d1 - min(d1,b1);
		d2 = d2 - min(d2,b2);
		d3 = d3 - min(d3,b3);
		b1 = b1 - min(aa,b1);
		b2 = b2 - min(bb,b2);
		b3 = b3 - min(cc,b3);//这个地方写错了,调试半天才调试出来,下次写代码要认真写,不然会大幅度降低写代码的效率
		long long  sum = d1 + d2 + d3 + b1 + b2 + b3;
		sum /= 2;
		ans -= sum;
		cout << ans << endl;
	}
}

H.Nihongo wa Muzukashii Desu
题意:本题就是给你一些后缀,这些后缀可以替换成其他语言的后缀,然后给你一些单词以这些后缀为结尾,让你全部替换成另外一种语言。
思路:我觉得这题主要是考察你substr函数的用法,你要会从一个长字符串提取它的后缀,然后根据题目中给你的后缀长度分类讨论,替换就行。

string s;
string s1 = s.substr(index, len)//就是从s字符串的下标为index截复制长度为len的字符串给s1.

代码:

#include <bits/stdc++.h>

using namespace std;

int main()
{
	int t;
	cin >> t;
	while(t -- )
	{
		string s;
		cin >> s;
		int len = s.length();
		// cout << "!!!!!!!!";
		if(len <= 5) cout << s << endl;
		else if(s == "ikimasu" ) cout << "itte\n";
		else if(len == 6)
		{
			if(s == "gimasu")	cout << "ide" << endl;
			else if(s == "kimasu")	cout << "ite" << endl;
			else if(s == "mimasu" || s == "bimasu" || s == "nimasu")	cout << "nde" << endl;
			else if(s == "rimasu") cout << "tte" << endl;
		}
		else if(len >= 7)
		{
			string s1 = s.substr(len - 7, 7);
			string s2 = s.substr(len - 6, 6);
			if(s1 == "shimasu") cout << s.substr(0,len - 7) << "shite\n";
			else if(s1 == "chimasu") cout << s.substr(0,len - 7) << "tte\n";
			else if(s2 == "gimasu") cout << s.substr(0,len - 6) << "ide\n";
			else if(s2 == "kimasu") cout << s.substr(0,len - 6) << "ite\n";
			else if(s2 == "mimasu" || s2 == "bimasu" || s2 == "nimasu") cout << s.substr(0,len - 6) << "nde\n";
			else if(s2 == "rimasu") cout << s.substr(0,len - 6) << "tte\n";

		}
	}
	return 0;
}

K.K-skip Permutation
题意:给你一个数字n和一个数字k,然后你要将1 ~ n进行排列使前一个数减去后面一个数的差为k这种情况最多。
思路:
(1)开一个空的vector和bool数组b
(2)每次向vector插入一个比上次多k的数x,并使b[x]变为true
(3)如果x大于n就找到没有放过的数,放到vector
(4) vector集合里面的元素个数等于n就跳出循环
代码:

#include <bits/stdc++.h>

using namespace std;

int n, k;
vector<int> a;
bool b[1000010];

int main()
{
	cin >> n >> k;
	int x = 1, num = 2;
	while(a.size() < n)
	{
		if(x <= n) 
		{
			a.push_back(x);
			b[x] = true;
		}
		x += k;
		if(x > n)
		{
			x = num ++;
			while(b[num] == true) num ++;
			
		}
	}
	for(int i = 0; i < n; i ++ ){
		cout << a[i];
		if(i != n - 1) cout << " ";
	}
	return  0;
}

M.True Story
题意:给你n个人,推迟登机时间的次数k,开始距离飞机场的距离,开始的登机时间,和每个人的速度,以及k次改签时间发布时间和改签的时间。如果一个人的速度在登机时间之前达不到机场,他就不赶往机场,如果改签后算下自己的速度能在飞机起飞时间之前赶往机场他就行动,问你最多有多少人能赶往机场。
思路:我是先根据他们的速度算出他们到达机场需要的时间,向上取整,然后再将飞机新的起飞时间和和宣布时间进行做差,就是他们能用来赶往机场的时间,然后取个最大值,如果最大值比他们需要赶往机场的时间多或者相等,就表明他们能赶往机场,模拟一遍就过。

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

LL n, k, x, p0;
LL s[100010];//速度
LL aa[100010];
LL bb[100010];
LL cha[100010];
LL need[100010];

int main()
{
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin >> n >> k >> x >> p0;
	for(int i = 1; i <= n; i ++ )	cin >> s[i];
	//需要的时间
	for(int i = 1; i <= n; i ++ )
	{
		int mod = x % s[i];
		if(mod == 0) need[i] = x / s[i];
		else need[i] = x / s[i] + 1;
	}
	for(int i = 1; i <= k; i ++ ) cin >> aa[i];
	for(int i = 1; i <= k; i ++ ) cin >> bb[i];
	for(int i = 1; i <= k; i ++ ) cha[i] = bb[i] - aa[i];
	sort(cha + 1, cha + 1 + k);
	LL maxn = cha[k];
	int ans = 0;
	for(int i = 1; i <= n; i ++ ) if(need[i] <= maxn) ans ++;
	cout << ans << endl;
	return 0;
} 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值