比赛链接:https://codeforces.com/contest/1741
A:
题意:比较两个字符串的大小,其大小规则满足:
方法:分类讨论
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
string a,b;
int t;
int main(){
cin>>t;
while(t--){
cin>>a>>b;
int la=a.size(),lb=b.size();
if(a==b) cout<<"=\n";
else if(a[la-1]==b[lb-1]&&a[la-1]=='S'){
if(la>lb) cout<<"<\n";
else if(la==lb) cout<<"=\n";
else cout<<">\n";
}
else if(a[la-1]==b[lb-1]&&a[la-1]=='L'){
if(la>lb) cout<<">\n";
else if(la==lb) cout<<"=\n";
else cout<<"<\n";
}
else{
if(a[la-1]=='L'&&(b[lb-1]=='M'||b[lb-1]=='S')||a[la-1]=='M'&&b[lb-1]=='S')
cout<<">\n";
else if(b[lb-1]=='L'&&(a[la-1]=='M'||a[la-1]=='S')||b[lb-1]=='M'&&a[la-1]=='S'){
cout<<"<\n";
}
}
}
}
B:
题意:给出一个数组的长度N,问是否能构造“数组中相邻元素至少有一个差值为1的数组”
样例1解释:
N=4 数组:【3 4 2 1】。(我们用idx表示数组下标)
idx=1时,其右边满足|a【idx】-a【idx+1】|=1
idx=2时,其左边满足|a【idx】-a【idx-1】|=1
idx=3时,其右边满足|a【idx】-a【idx+1】|=1
idx=4时,其左边满足|a【idx】-a【idx-1】|=1
方法:通过分析样例,我们发现,只需要将1-n个元素依次进行错位就行。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
int t;
int n;
int main(){
cin>>t;
while(t--){
cin>>n;
if(n==3){
cout<<"-1\n";continue;
}
cout<<n<<" "<<n-1<<" ";
for(int i=1;i<=n-2;i++) cout<<i<<" ";
cout<<"\n";
}
}
C:
题意:给一个长度为N的数组,问是否能够分成若干段,使每段的sum相等,定义Thinkeness为若干段中,长度最长的的值,求Min(Thinkness)。
方法:枚举。假设N=3,依次枚举区间1-1,1-2,1-3,sum的值。以该值进行后面区间的划分,如果能够划分若干个sum值相等的区间,则记录一次Thinkness,枚举中可能会产生多个区间,只需要每次取Thinkness,最后再取Min(Thinkness)。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
int t,n;
int a[N],sum[N];
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];//前缀和
int ans=n;
for(int i=1;i<=n;i++){
int ok=1,now=0,x=i,c=0;
/*ok表示这个区间是否可行,now表示每个区间段的总值,x表示第一个区间的长度,c统计区间长度*/
for(int j=1;j<=n;j++){
now+=a[j],c++;
if(now>sum[i]){
ok=0;break;
}
if(now==sum[i]){
x=max(x,c);//取最大区间
now=0;c=0;//归零
}
}
if(now>0) ok=0;//最后一个区间存在,且不满足条件
if(ok) ans=min(ans,x);//取所有情况的Min(Thinkness)
}
cout<<ans<<"\n";
}
}
D:
题意:给一棵完全二叉树,可以交换某个父节点的两个儿子,求使叶子节点单调递增的最小步数。
样例1第四步后结果为:
方法:分治
若【L,mid】有大于【mid,R】的值,则就交换一次,然后交换完之后,再与最终结果进行比对,如果能够形成从左到右的单调递增序列,则输出ans,否则输出-1。
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+10;
int a[N],b[N];
int ans,n;
void dfs(int L,int R){
if(L==R) return;
int mid=L+R>>1;
dfs(L,mid),dfs(mid+1,R);
if(a[L]>a[R]){
ans++;
for(int i=L;i<=mid;i++) swap(a[i],a[i+(R-L)/2+1]);//交换区间里面的左右部分
}
}
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];b[i]=a[i];
}
sort(b+1,b+1+n);
ans=0;dfs(1,n);
for(int i=1;i<=n;i++)
if(a[i]!=b[i]){
cout<<"-1\n";return;
}
cout<<ans<<"\n";
}
signed main(){
int T;cin>>T;
while(T--){
solve();
}
}