Codeforces Round #836 (Div. 2) A~D题解

原题地址:Codeforces Round #836 (Div. 2)

题目:A. SSeeeeiinngg DDoouubbllee

题意:

          给定一个长度为n的字符串s,让你构造一个长度为2n的字符串ans满足回文字符串,并且ans的字符是通过s加倍而来的,那么我们只需要正着输出s,然后倒着在输出一边s即可满足回文字符串。

代码:

#include<bits/stdc++.h> 
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<string.h> 
typedef long long ll;
using namespace std;
const int N = 2e5+10;
const int mod = 1e9+7;
ll a[N],b[N],c[N];
//string s1[N],s2[N],s3[N];
int main(void)
{
	int t;
	cin >> t;
	while(t--)
	{
		string s;
		cin >> s;
		for(int i=0;i<s.length();i++)
		{
			cout << s[i];
		} 
		for(int i=s.length()-1;i>=0;i--)
		{
			cout << s[i];
		} 
		cout << endl;
	}
	return 0;
 } 

题目:B. XOR = Average

题意:

         给定一个长度n,让你构造一个长度为n的数组n,满足:

做法:

        当n为奇数时,因为a异或a等于0,我们通过构造n个1,或者说满足数组全为一样的数即可满足上式,因为前n-1个异或为0,第n个数与0异或等于本身。

        当n为偶数时,我们可以构造前n-2个数都是2,然后后面俩个数是1 和 3,因为1和3的异或和刚好等于2,所以左边最后为2,右边也为2.

代码:

#include<bits/stdc++.h> 
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<string.h> 
typedef long long ll;
using namespace std;
const int N = 2e5+10;
const int mod = 1e9+7;
ll a[N],b[N],c[N];
//string s1[N],s2[N],s3[N];
int main(void)
{
//	cout << (0^3^3^2) << endl;
	int t;
	cin >> t;
	while(t--)
	{
		int n;
		cin >> n;
		if(n%2==1)
		{
			for(int i=1;i<=n;i++)
			{
				cout << 1 << " ";
			}
			cout << endl;
		}
		else
		{
			for(int i=1;i<=n-2;i++)
			{
				cout << 2 << " ";
			}
			cout << 1 << " " << 3 << endl;
		}
	}
	return 0;
 } 

题目:C. Almost All Multiples

题意:

        给定长度n和一个x,求构造一个长度为n的permutation数组满足 a[1] = x,a[n] = 1。

保证a[i]的每个元素的值,都是i的倍数,如a[2] = 4,4是2的倍数,所以a[2]可以是4,但是a[2]不可以是3.求出字典序最小的数列。

做法:

        我们可以刚开始将a[1] = x,a[n] = 1,其他a[i] = i,i是2~n-1,然后我们会发现n这个数是多出来的

关键就在于这个n插到哪个位置能够构造的数组字典序最小,比如 n=8,x=2,那么可以刚开始构造一个数组为 2 k 3 4 5 6 7 1, 此时8可以插到k里,但是要想最小,需要把4插到k里面,然后再把8的位置插到4里,答案便是 2 4 3 8 5 6 7 1,所以我们根据这种思路模拟一边即可。

如果n = 4,x=2,那么初始 2 k 3 1,只有4能插到k,后面的数不能插到k,所以构造的数为2 4 3 1 

代码:

#include<bits/stdc++.h> 
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<string.h> 
typedef long long ll;
using namespace std;
const int N = 2e5+10;
const int mod = 1e9+7;
ll a[N],b[N],c[N];
//string s1[N],s2[N],s3[N];
int main(void)
{
//	cout << (0^3^3^2) << endl;
	int t;
	cin >> t;
	while(t--)
	{
		int n,x;
		cin >> n >> x;
		a[1] = x;
		a[n] = 1;
		b[x] = 1;
		b[1] = 1;
		for(int i=2;i<=n-1;i++)
		{
			a[i] = i;
		}
		if(n%x!=0)
		{
			cout << -1 << endl;
		}
		else
		{
			int mul=2;
			ll num = mul*x;
			int flag=0;
			while(num<n)
			{
				if(n%num==0)
				{
					a[x] = num;
					flag = 1;	
					x = num;
					mul = 1;
				}
				mul++;
				num = mul*x;
			} 
			if(x!=n)
			{
				a[x] = n;
			}
			for(int i=1;i<=n;i++)
			{
				cout << a[i] << " ";
			}
			cout << endl;
		}
	}
	return 0;
 } 

题目:D. Range = √Sum

题意:

        让你构造一个长度为n的数组a,且保证每个元素各不相同,满足下列式子

 做法:

        我们可以让最大值为3的倍数,当n为偶数时,max = (n/2)*3,min = max-n,然后剩余的n-2个数补中间的,如n = 6,max = 9,min = 3,还有四个数 补上 4 5 7 8即可,遇到6就跳过,所以构造的数组为 3 4 5 7 8 9,当n = 4时,a= 2 3 5 6

当n为奇数时,max = ((n+1)/2)*3+1,min = max-n-1,然后剩余的数中间补,上半部比下半部多一个,如n=5,max = 10,min = 4,其余三个补从大往小补,依次 9 8 5,如n = 7,max = 13,min = 5 其余五个依次补 12 11 10 9 4即可

代码:

#include<bits/stdc++.h> 
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<string.h> 
typedef long long ll;
using namespace std;
const int N = 3e5+10;
const int mod = 1e9+7;
ll a[N],b[N],c[N];
//string s1[N],s2[N],s3[N];
int main(void)
{
//	cout << (0^3^3^2) << endl;
	int t;
	cin >> t;
	while(t--)
	{
		int n;
		cin >> n;
		if(n%2==1)
		{
			ll sum = (n+1)*(n+1);
			ll ma = 3*((n+1)/2)+1;
			ll mi = ma-n-1;
			a[1] = ma;
			a[2] = mi;
			int num1 = (sum-ma-mi);
			int index = ma-1;
			for(int i=3;i<=n;i++)
			{
				if(num1<=index)
				{
					a[i] = num1;
					break;
				}
				a[i] = index;
				index--;
				num1 -= index;
				
			}
		}
		else
		{
			ll sum = n*n;
			ll ma = 3*(n/2);
			ll mi = ma-n;
			a[1] = ma;
			a[2] = mi;
			int index=mi+1;
			for(int i=3;i<=n;i++)
			{
				a[i] = index;
				index++;
				if(index==(ma+mi)/2)
				{
					index++;
				}
			}
		}
		for(int i=1;i<=n;i++)
		{
			cout << a[i] << " ";
		}
		cout << endl;
	}
	return 0;
 } 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值