AtCoder Beginner Contest 234题解(A~D)

AtCoder Beginner Contest 234题解


A - Weird Function

【题目链接】

题解:套公式就行

【代码实现】

#include <iostream>
#include <cstring>
#include <vector>
#include <set>
#include <algorithm>
#include<unordered_map>

using namespace std;

typedef long long LL;
const int N = 1e5 + 10; 
LL f1(LL t)
{
	return t * t + 2 * t + 3;
}

LL get_ans(LL t)
{
	LL k3 = f1(f1(t) + t);
	LL k4 = f1(f1(t));
	LL ans = f1(k3 + k4);
	return ans;
}
int main()
{
	LL n;
	cin >> n;

	cout << get_ans(n);
		 
    return 0;
}

B - Longest Segment

【题目链接】B - Longest Segment (atcoder.jp)

**题意:**求平面n对点中两点的最长距离。

**考察知识点:**数学:两点距离公式(欧氏距离)

#include <iostream>
#include <cstring>
#include <vector>
#include <set>
#include<cmath>
#include <algorithm>
#include<unordered_map>

using namespace std;

typedef pair<int, int>PII;
vector<PII> a;

const int N = 1e5 + 10; 

int main()
{
	double n;
	scanf("%lf", &n);
	
	double ans = -1e10;
	while(n --)
	{
		double x, y;
		scanf("%lf%lf", &x, &y);
		a.push_back({x, y});
	}
	for(auto &t : a )
		for(auto &k : a)
		{
			double x1 = t.first, y1 = t.second;
			double x2 = k.first, y2 = k.second;
			double distance = (double)sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)) / 1.0;
			ans = max(ans, distance);
		}
	printf("%.10lf", ans);	
	
		 
    return 0;
}

C - Happy New Year!

【题目链接】C - Happy New Year! (atcoder.jp)

题意:

输入一个数n,输出对应的只含有2和0的数(年)

【错误】暴力枚举判断,很快就爆了…

#include <iostream>
#include <cstring>
#include <vector>
#include <set>
#include <algorithm>
#include<unordered_map>

using namespace std;

typedef long long LL;

const int N = 1e5 + 10; 

bool check(string s)
{
	if( s.find('1') != -1 || s.find('3')!=-1 || s.find('4')!=-1 || s.find('5')!=-1 || s.find('6')!=-1 || s.find('7')!=-1 || s.find('8')!=-1 || s.find('9')!=-1 || s[0] != '2')
		return true;
	else 
		return false;	
}

int main()
{
	LL n;
	cin >> n;
	
	vector<LL> arr;
	for(LL i = 2; i < 202000; i ++)
	{
		string s = to_string(i);
		if(check(s)) continue;
		else
		{
			
			LL x = stoll(s);
			arr.push_back(x);
		}
	}
	
	cout << arr[n - 1];

		 
    return 0;
}

【正解】

看了官方题解:

让我们枚举满足条件的整数

  1. 2
  2. 20
  3. 22
  4. 200
  5. 202
  6. 220
  7. 222
  8. 2000
  9. 2002
  10. 2020
  11. 2022

仔细观察没有发现每一次只变化一位,有没有联想到二进制进位的规律呢?没错就是这样!

4的二进制:100,年份:200

11的二进制:1011,年份:2022

不难发现,答案就是把输入数对应二进制的1全部变为2,0则保持不变即可,太妙了~

考察知识点:进制转换,模拟

【代码实现】

短除法:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>

using namespace std;

typedef long long LL;
const int N = 1e6+10;

int main()
{
	LL n;
	cin >> n;
	
	//将n转为2进制: 1变为0, 0则保持 
	string res = "";
	while(n)
	{
		if(n % 2 == 0) res = '0' + res;
		else res = '2' + res;
		n /= 2;
	} 
	
	cout << res;
	return 0;
}

位运算:

	string res = "";

	while(k)
	{
		if(k&1) res = "2" + res;
		else res = "0" + res;
		k >>= 1;
	}	
	
	cout << res << endl;

D - Prefix K-th Max

【题目链接】D - Prefix K-th Max (atcoder.jp)

题意:

给你1~n的排列,然后要你求前k、k+1、k+2…n项第k大的数

思路:

前k项第k大的数,实际上就是最小的那个数(num1),然后我们取看前k + 1项:如果第k + 1项的数(a[k+1]) < num1,还是输出num1;如果a[k + 1] > num1,那么就输出仅次于num1的序列中最小的数num2,以此类推,直至结束。

题解:

我们可以用一个小根堆,拿到前k项中最小的那个数num1(时间复杂度O(1)),当判断前k + 1项,则看a[k + 1] > 堆顶?

  • a[k + 1] > 堆顶元素,则弹出,然后再输出新的堆顶元素
  • a[k + 1] < 堆顶元素,继续保持并输出它即可

**考察知识点:**优先队列,小根堆

【代码实现】

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>

using namespace std;

int main()
{
	
	int n, k;
	cin >> n >> k;
	vector<int> a(n);
	for(int i = 0; i < n; i ++) cin >> a[i];// 如果直接输入要给vector开大小
// 	{
// 	    int x;
// 	    cin >> x;
// 	    a.push_back(x);
// 	}

	// 优先队列:小根堆
	priority_queue<int, vector<int>, greater<int>> heap;
	// 前k项加入堆中
	for(int i = 0; i < k; i ++) heap.push(a[i]);
	
	cout << heap.top() << endl;
	for(int i = k; i < n; i ++)// 观察前 k + 1项 
	{
		if(a[i] > heap.top())
		{
			heap.pop();
			heap.push(a[i]); 
		}
		cout << heap.top() << endl;
	 } 
	return 0;
}

E - Arithmetic Number

【题目链接】E - Arithmetic Number (atcoder.jp)

题意:

**思路:**DFS待补

题解:

考察知识点:

【代码实现】


F - Reordering

**思路:**DP + 组合数:待补

E、F,dfs和dp都是弱项,等具体学习练习了再回来补题,QAQ…

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值