codeforces比赛(3):codeforces good_bye_2023

发布时间 2023-12-31 20:07:32作者: Tom-catlll

A、2023

跳转原题点击此:A题地址

1、题目大意

  在一个乘积可能等于2023的数组a中去掉了k个数,得到新的长度为n的b数列。请你输出k个数,使得这k个数与b数列相乘为2023.如果不存在则输出No。

2、题目解析

  因为这道题的n和k都是不超过5,所以我们只需要算出b数组的乘积是否是2023的因数,不是就输出No,否则直接输出 \(2023/b数组的乘积\)\(k-1\)个 1 即可。

3、具体代码

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N = 100;

int T;
int n, k;
int f[N];

void solve()
{
	cin >> n >> k;
	ll ans = 1;
	for(int i = 1; i <= n; i++)
	{
		cin >> f[i];
		ans *= f[i];
	}
	if(2023 % ans != 0 || ans > 2023)
	{
		cout << "No\n";
		return;
	}
	cout << "Yes\n";
	cout << 2023 / ans << " ";
	k--;
	while(k--)
	{
		cout << 1 << " ";
	}
	cout << endl;
}

int main()
{
	cin >> T;
	while (T--)
	{
		solve();
	}

	return 0;
}

 

B、Two Divisors

跳转原题点击此:B题地址

1、题目大意

  给你两个数a和b(a<b),他们是x的最大约数(不包括x本身),如6的两个最大约数是2、3。

2、题目解析

  如果b不是a的倍数,那么答案就是a和b的最小公倍数(最小公倍数定义);
  如果b是a的倍数,那么lcm(a,b)就为b,不符合要求。而b/a说明这是b能获得的最大倍数,所以答案为\(b*(b/a)\)。(说实话我是看样例看出来的)

3、具体代码

#include<bits/stdc++.h>

using namespace std;

const int N = 2e5+10;

int T;
int a, b;
int f[N];

int gcd(int a, int b)
{
	return b ? gcd(b, a % b) : a;
}
int lcm(int a, int b)
{
	return a / gcd(a, b) * b;
}

void solve()
{
	cin >> a >> b;
	if(a % b != 0 && b % a != 0)
	{
		cout << lcm(a, b) << endl;
		return;
	}
	else
	{
		int tmp = b / a;
		cout << tmp * b << endl;
	}
}

int main()
{
	cin >> T;
	while (T--)
	{
		solve();
	}

	return 0;
}

 

C、Training Before the Olympiad

跳转原题点击此:C题地址

1、题目大意

  玛和奥两个人玩一个游戏,对一组数列中进行以下操作:
  选中\(a_i\)\(a_j\),生成新的数x为\(\lfloor \frac{a_i + a_j}{2} \rfloor * 2\),并将\(a_i\)\(a_j\) 移出该数组 和 x添加进数组。当数组长度为1时游戏结束。其中玛是尽可能让结果越大越好,而奥反之(双方都选择最优解,且玛先操作)。
  注意每次让数组的前k个数字加入游戏,问你每次的结果是多少。

2、题目解析

  由于是向下取整,所以当一个奇数和一个偶数相加则会损失1。所以玛优先合并两个奇数,而奥优先合并一奇一偶。并且不管选中奇数还是偶数,最终生成的x一定是偶数
  并且我们发现,当存在三个奇数时,一定会损失1。因为先是玛合并两个奇数获得偶数,那么奥就合并偶数和奇数少掉一个1。所以损失的个数就是3的倍数。如果多余1个奇数,那么还会损伤1(两个奇数则不会)。至于偶数,根本没有影响。

3、具体代码

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
const int N = 2e5+10;

int T;
int n;
int f[N];


void solve()
{
	cin >> n;
	ll sum = 0, odd = 0;
	for(int i = 1; i <= n; i++)
	{
		cin >> f[i];
		sum += f[i];
		if(f[i] & 1)	// 该数是奇数时
			odd++;
		if(i == 1)	// 可以特判
		{
			cout << f[1] << " ";
			continue;
		}
			
		// 每三个奇数,会少掉一个1
		// 因为先是玛合并两个奇数获得偶数,那么奥就合并偶数和奇数少掉一个1
		ll tmp = odd / 3;	
		
		if(odd % 3 == 1)	// 多出一个奇数那么肯定也会减一,两个就不会
			tmp++;
		cout << sum - tmp << " ";
	}
	cout << endl;

}

int main()
{
	cin >> T;
	while (T--)
	{
		solve();
	}

	return 0;
}

 

D、Mathematical Problem

跳转原题点击此:D题地址

1、题目大意

  给你一个数n,输出的n个数,其每个数要满足以下三个条件:

  1. 其长度为n
  2. 这n个数的数字组成个数必须保持一致。如123、213、312,都由1个1、2、3组成(数字可以重复)
  3. 这n个数必须是某个数的平方数,

2、题目解析

  打表题目,通过暴力查看后面的数,发现满足条件的里面一定有由1、9、6和若干个0组成。

3、具体代码

#include<bits/stdc++.h>

using namespace std;

#define _1 first
#define _2 second

typedef long long ll; 
typedef pair<ll, ll>pii;
const int N = 2e5+10;
const int M = 1010;
const int INF = 1e9 + 10;

int T;
int n;
int f[N];

void solve() {
    int n;
    cin >> n;
    if (n == 1) // 1特判
    {
        cout << "1\n";
        return ;
    }
    cout << "196";
    for (int i = n - 3; i; i --) 
    	cout << "0";
    cout << "\n";
 	// 查看规律
    for (int i = 1; i < n; i += 2) 
    {
        int cnt = 3;
       	cout << "9";
        for (int k = 1; k <= i / 2; k ++) 
        	cout << "0", cnt ++;
        cout << "6";
        for (int k = 1; k <= i / 2; k ++) 
        	cout << "0", cnt ++;
        cout << "1";
        for (int k = cnt; k < n; k ++) 
        	cout << "0";
        cout << "\n";
    }
 
    for (int i = 1; i < n; i += 2) 
    {
        int cnt = 3;
        cout << "1";
        for (int k = 1; k <= i / 2; k ++) 
        	cout << "0", cnt ++;
        cout << "6";
        for (int k = 1; k <= i / 2; k ++) 
        	cout << "0", cnt ++;
        cout << "9";
        for (int k = cnt; k < n; k ++)
        	cout << "0";
        cout << "\n";
    }
}

int main()
{
	cin >> T;
	while (T--)
	{
		solve();
	}

	return 0;
}

 

E、F、G、H1、H2(未来补题)

已经完全超出我的能力范围了。要我很久很久才能补上。呜呜呜emmm