[2021-04-02]BNUZ套题比赛div3

52 篇文章 1 订阅
34 篇文章 0 订阅

A题:
已知需要a分钟睡觉,那么分三种情况:
1.a<=b,那么睡够a分钟,闹钟还是没响.
2.d>=c,那么他还没睡觉就被吵醒了.
3.先计算睡觉要多少个周期,即a-b为被b这个闹钟吵醒后还需要睡的分钟数,c-d就是它被每个c闹钟吵醒前能睡的分钟数,那么(a-b)/(c-d)就是需要睡觉的周期(注意:可能(a-b)/(c-d)不能整除,相当于你睡觉需要8分钟(a-b),你每次小盹5分钟(c-d),那么(a-b)/(c-d)=1但是其实你需要睡两次,即答案是2才对,所以这里需要特判一下).

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#define ll long long
using namespace std;
int main()
{
	int T;
	cin >> T;
	for (int i = 0; i < T; i++)
	{
		ll a, b, c, d;
		cin >> a >> b >> c >> d;
		ll  ans = b;
		if (a <= b)
		{
			cout << ans << endl;
			continue;
		}
		if (d >= c) ans = -1;
		else 
		{
			ll t = (a - b) / (c - d);
			//(a-b)%(c-d)为特判
			ans += (t+ bool((a - b) % (c - d))) * c;
		}
		cout << ans << endl;
	}
	return 0;
}

B题:
水题就不多说了

#include<iostream>
#include<string>
#define ll long long
using namespace std;
int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		string a;
		ll pos1 = 0, pos2 = 0, pos3 = 0, ans = 1e10, minnum = 1e10;
		cin >> a;
		a = '0' + a;
		for (int i = 1; i < a.length(); i++) {
			if (a[i] == '1')pos1 = i;
			else if (a[i] == '2')pos2 = i;
			else if (a[i] == '3')pos3 = i;
			if (pos1 && pos2 && pos3) {
				ll temp = min(pos1, min(pos2, pos3));
				ans = min(ans, i - temp + 1);
			}
		}
		if (ans != 1e10)
			cout << ans << endl;
		else
			cout << '0' << endl;
	}
}

C题:
输入n,创造一个2n边型,问包裹住这个2n边型的最小正方形的边长是多少:
在这里插入图片描述

#include<iostream>
using namespace std;
#include<cmath>
#include<iomanip>
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		int n;
		cin >> n;
		n *= 2;
		double ans = 1.0 / tan(3.1415926535 / n);
		cout << setprecision(10) << ans << endl;
	}

}

D题:
和上一题一样,只不过这里的n是奇数:
推到过程如下:
在这里插入图片描述

#include<iostream>
using namespace std;
#include<cmath>
#include<iomanip>
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		int n;
		cin >> n;
		n *= 2;
		double ac = 1.0 / sin(3.1415926535 / n);
		double ab = cos(3.1415926535 / (2 * n)) * ac;
		printf("%.9lf\n", ab);
	}
}

E题:
说白了就是判断人在人行道时不能有车能撞到他.

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#define ll long long
int person[5];
int car[5][5];
using namespace std;
int main()
{
	int ans = 0;
	for (int i = 0; i < 4; i++) {
		cin >> car[i][0] >> car[i][1] >> car[i][2] >> person[i];
	}
	for (int i = 0; i < 4; i++) {
		if(person[i]){
			for (int j = 0; j < 4; j++) {
				if (car[i][j]) { ans = 1; break; }
			}
			for (int j = 1; j <= 3; j++) {
				if(car[(i+j)%4][(j-1)%3]) { ans = 1; break; }
			}
		}
	}
	if (ans)cout << "YES" << endl;
	else cout << "NO" << endl;
	return 0;
}

F题:DFS或者DP(都写不出来了)
DP链接:
https :blog.csdn.net/a664607530/article/details/72842135
解题思路:DP,每一层的左楼梯和右楼梯都有两个选择策略,左楼梯可以是下面层的右楼梯走过来的,也可以是下面层的左楼梯先去关灯在走回来的,右楼梯一样。在特殊考虑一下相当只有一层的。
注解和代码如下:

#pragma warning(disable:4996)
#include<iostream>
using namespace std;
#include<cmath>
#include<iomanip>
#include<string>
#include<cstring>
const int INF = 0x3f3f3f3f;
int n, m;
char ch[20][120];
int l[20], r[20], visit[20], dp[20][2];
int main()
{
	while (cin>>n>>m)
	{
		memset(visit, 0, sizeof visit);
		memset(r, 0, sizeof r);
		memset(l, 0, sizeof l);
		for (int i = n; i >= 1; i--)
		{
			cin >> ch[i] + 1;
			for (int j = 2; j <= m + 1; j++)
				if (ch[i][j] == '1') { l[i] = j;visit[i] = 1; break; }
			for (int j = m + 1; j >= 2; j--)
				if (ch[i][j] == '1') {r[i] = j;break; }
		}
		//特判只有一层的情况
		int x = n;
		while (!visit[x--] && x >= 1) n--;
		if (n == 1) { printf("%d\n", r[1] ? r[1] - 1 : 0); continue; }
		//普遍情况
		memset(dp, INF, sizeof dp);
		dp[1][0] = r[1] ? (r[1] - 1) * 2 : 0, dp[1][1] = m + 1;
		for (int i = 2; i < n; i++)
		{
			//如果这一层都没有灯是开的话
			if (!visit[i])
			{
				dp[i][0] = dp[i - 1][0] + 1;
				dp[i][1] = dp[i - 1][1] + 1;
				continue;
			}
			//左楼梯下面的左楼梯先去关灯在走回来的
			dp[i][0] = min(dp[i - 1][0] + 2 * (r[i] - 1) + 1, dp[i][0]);
			//左楼梯下面层的右楼梯走过来的
			dp[i][0] = min(dp[i - 1][1] + m + 1 + 1, dp[i][0]);
			//右楼梯下面层的右楼梯关灯走过来的
			dp[i][1] = min(dp[i - 1][1] + 2 * (m + 2 - l[i]) + 1, dp[i][1]);
			//右楼梯下面的左楼梯走过来的
			dp[i][1] = min(dp[i - 1][0] + m + 2, dp[i][1]);
		}
		int ans = min(dp[n - 1][0] + r[n], dp[n - 1][1] + 1 + m + 2 - l[n]);
		printf("%d\n", ans);
	}
	return 0;
}

这次的题非常的NICE

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值