A 题目链接:https://codeforces.com/contest/1758/problem/A
input:
4
a
sururu
errorgorn
anutforajaroftuna
output:
aa
suurruurruus
rgnororerrerorongr
aannuuttffoorraajjaarrooffttuunnaa
题意:
给一个字符串s,每个字母数量变成原来的两倍(seeing -> sseeeeiinngg),试构造出一个回文串
思路:
直接将原串正序输出然后倒序输出即可
代码如下:
#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=2e5+10;
int t,n;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--)
{
string s;
cin>>s;
cout<<s;
for(int i=s.length()-1;i>=0;i--)
{
cout<<s[i];
}
cout<<endl;
}
return 0;
}
B 题目链接:https://codeforces.com/contest/1758/problem/B
input:
3
1
4
3
output:
69
13 2 8 1
7 7 7
题意:
构造一个长度为 n 的序列,使序列所有元素异或起来的值等于序列元素的均值
思路:
分类讨论
n 为奇数的情况下,直接构造为同一个数即可
n 为偶数的情况下:
1. n 不为4的倍数的情况下,首先可以得到1和3的异或值是2,所以构造 n / 2 对1和3,两两异或得到 n / 2 个2,且 n / 2为奇数,所以异或值等于2,均值也等于2
2. n 为4的倍数的情况,在情况1的条件下,构造 n / 2 - 1 对1和3,2个2即可
代码如下:
#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=2e5+10;
int t,n;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--)
{
cin>>n;
if(n&1)
{
for(int i=1;i<=n;i++)
{
cout<<n<<" ";
}
cout<<endl;
}
else
{
if(n%4)
{
for(int i=1;i<=n/2;i++)
{
cout<<1<<" ";
}
for(int i=n/2+1;i<=n;i++)
{
cout<<3<<" ";
}
}
else
{
cout<<"2 2 ";
for(int i=1;i<=n/2-1;i++)
{
cout<<1<<" ";
}
for(int i=n/2;i<=n-2;i++)
{
cout<<3<<" ";
}
}
cout<<endl;
}
}
return 0;
}
C 题目链接:https://codeforces.com/contest/1758/problem/C
input:
3
3 3
4 2
5 4
output:
3 2 1
2 4 3 1
-1
题意:
给定 n 和 x,试构造一个排列 p ,满足 p1 == x ,pn == 1,且任意 1<= i <= n-1 满足 pi % i == 0
并使字典序最小
思路:
首先,对于一个排列 p ,把 x 放在第1位,1放在第 n 位,当前空位是 x。
显而易见,要想满足条件,大多数元素一定要放在和下标一致的位置上才合法,并且 目前没有位置的 n 一定不可能放在 x 之前。所以可以推出一个重要结论:n 如果不能放在第 x 位上,一定无解!
当我们把 n 放在第 x 位上之后,我们可以发现,当前排列不一定满足字典序最小,所以说,我们要往后搜索满足可以和当前 n 置换的元素,尽量将大的数置换到后面(细节见代码)
代码如下:
#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=2e5+10;
int t,n,x;
int a[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--)
{
cin>>n>>x;
if(n%x!=0)
{
cout<<-1<<endl;
continue;
}
for(int i=2;i<n;i++)
{
a[i]=i;
}
a[x]=n;
a[1]=x;
a[n]=1;
int k=x;
for(int i=1;x*i<n;i++)
{
if(n%(x*i)==0&&(x*i)%k==0)
{
swap(a[k],a[x*i]);
k=x*i;
}
}
for(int i=1;i<=n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
return 0;
}
D 题目链接:https://codeforces.com/contest/1758/problem/D
input:
3
2
5
4
output:
3 1
20 29 18 26 28
25 21 23 31
题意:
给定一个数 n ,是构造长度为 n 的数组 a,满足 a 的 最大值和最小值的差等于 a 中所有元素加和的开方
思路:
分类讨论:
n 为偶数的情况下,比较好构造,直接以 n 为中心 ,构造 n / 2 个依次小 1的数,构造 n / 2个依次大1的数,总和是 n ^ 2
n为奇数的情况下,构造 n - ( n + 1 ) / 2 + 2 ~ n , n + 3 ~ n + ( n + 1 ) / 2 + 2 , 总和是 ( n + 1 ) ^ 2
和 B 题一样,纯写样例写出来的,不会数学证明,见谅~
代码如下:
#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=2e5+10;
int t,n;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--)
{
cin>>n;
if(n&1)
{
for(int i=n-(n+1)/2+2;i<=n;i++)
{
cout<<i<<" ";
}
for(int i=n+3;i<=n+(n+1)/2+2;i++)
{
cout<<i<<" ";
}
cout<<endl;
}
else
{
int k=n/2;
int i=n-1;
while(k--)
{
cout<<i<<" ";
i--;
}
k=n/2;
i=n+1;
while(k--)
{
cout<<i<<" ";
i++;
}
cout<<endl;
}
}
return 0;
}