Codeforces Round #826 (Div. 3)(A~F)

A. Compare T-Shirt Sizes

给出衣服尺码,判断两个尺码的大小关系。

思路:模拟。

AC Code:

#include <bits/stdc++.h>

typedef long long ll;
const int N=2e5+5;
int t;
std::string a,b;

int main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	std::cin>>t;
	while(t--){
		std::cin>>a>>b;
		int lena=a.length(),lenb=b.length();
		if(a==b){
			std::cout<<'='<<'\n';
		}
		else if(a[lena-1]==b[lenb-1]&&a[lena-1]=='S'){
			if(lena>lenb){
				std::cout<<'<'<<'\n';
			}
			else if(lena==lenb){
				std::cout<<'='<<'\n';
			}
			else if(lena<lenb){
				std::cout<<'>'<<'\n';
			}
		}
		else if(a[lena-1]==b[lenb-1]&&a[lena-1]=='L'){
			if(lena>lenb){
				std::cout<<'>'<<'\n';
			}
			else if(lena==lenb){
				std::cout<<'='<<'\n';
			}
			else if(lena<lenb){
				std::cout<<'<'<<'\n';
			}
		}
		else{
			if(a[lena-1]=='L'&&(b[lenb-1]=='M'||b[lenb-1]=='S')||a[lena-1]=='M'&&b[lenb-1]=='S'){
				std::cout<<'>'<<'\n';
			}
			else if(b[lenb-1]=='L'&&(a[lena-1]=='M'||a[lena-1]=='S')||b[lenb-1]=='M'&&a[lena-1]=='S'){
				std::cout<<'<'<<'\n';
			}
		}
	}
	return 0;
}

B. Funny Permutation

 

给出一个数字n,构造一个大小为n的permutation,使得对于每个位置i,都满足p[i]!=i且每个数相邻的数至少有一个数p[i]-1或p[i]+1。

思路:把顺序序列从中间截断,按顺序依次递增输出即可。

AC Code:

#include <bits/stdc++.h>

typedef long long ll;
const int N=2e5+5;
int t,n;
int a[N];

int main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	std::cin>>t;
	while(t--){
		std::cin>>n;
		if(n==3){
			std::cout<<-1<<'\n';
			continue;
		}
		int pos=(n+1)/2;
		for(int i=pos+1;i<=n;i++){
			std::cout<<i<<' ';
		}
		for(int i=1;i<=pos;i++){
			std::cout<<i<<' ';
		}
		std::cout<<'\n';
	}
	return 0;
}

os:还搞了好几次WA1,乐

C. Minimize the Thickness

给出一个数组,将它分成若干子数组,使得每个子数组的和都相等,对于同一个和,最小化所有段的最大值 。

思路:前缀和,枚举每个全部数之和的因数的前缀和,不断更新满足条件的答案。

AC Code:

#include <bits/stdc++.h>

typedef long long ll;
#define int long long
const int N=2e3+5;
int t,n;
ll a[N],dif[N];

signed main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	std::cin>>t;
	while(t--){
		std::cin>>n;
		std::vector<ll>vec;
		for(int i=1;i<=n;i++){
			std::cin>>a[i];
			dif[i]=dif[i-1]+a[i];
		}
		for(int i=1;i<=n;i++){
			if(dif[n]%dif[i]==0){
				vec.push_back(dif[i]);
			}
		}
		int ans=1e9;
		int len=vec.size();
		for(int i=0;i<len;i++){
			int pos=0,dis=-1;
			for(int j=1;j<=n;j++){
				if(dif[j]-dif[pos]==vec[i]){
					dis=std::max(dis,j-pos);
					pos=j;
				}
			}
			if(pos==n) ans=std::min(ans,dis);
		}
		std::cout<<ans<<'\n';
	}
	return 0;
}

os:注意枚举因数的时候,是每个段之间的差都是这个因数。一开始我想成整除即可,WA两发,sad。

D. Masha and a Beautiful Tree

给出一个有2^n个数的permutation数组,分别位于n层满二叉树的叶节点。每次操作可以交换一个根节点的两个子树,问最少能通过几次操作使得数组有序,或者无法操作使得有序,输出-1。

思路: (1)归并:判断需要操作的位置和-1一样是判断区间边界的大小,具体看代码;

(2)DFS搜索:每次搜索两半数组的范围,注意判断条件是对于一段最左侧最右侧的值进行判断,判-1的条件是对于一个区间排序完成后最小值和最大值的计算。

AC Code:

(1)

#include <bits/stdc++.h>

typedef long long ll;
const int N=262144+5;
int t,n,ans;
int a[N],tmp[N];
bool flag;

void merge_sort(int a[],int l,int r){
    if(l>=r) return;
    int mid=(l+r)>>1;
    merge_sort(a,l,mid);
    merge_sort(a,mid+1,r);
    int k=0,i=l,j=mid+1;
    while(i<=mid&&j<=r){
        if(a[i]<a[j]) tmp[++k]=a[i++];
        else tmp[++k]=a[j++];
    }
    if(i==l) ans++;
    if(i!=l&&j!=mid+1) flag=true;
    while(i<=mid) tmp[++k]=a[i++];
    while(j<=r) tmp[++k]=a[j++];
    for(int i=l,j=1;i<=r;j++,i++) a[i]=tmp[j];
}

int main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	std::cin>>t;
	while(t--){
		memset(a,0,sizeof(a));
		memset(tmp,0,sizeof(tmp));
		std::cin>>n;
		for(int i=1;i<=n;i++){
			std::cin>>a[i];
		}
		ans=0;
		flag=false;
		merge_sort(a,1,n);
		if(flag) std::cout<<-1<<'\n';
		else std::cout<<ans<<'\n';
	}
	return 0;
}

(2)

#include <bits/stdc++.h>

typedef long long ll;
const int N=262144+5;
int t,n,ans;
int a[N];
bool flag;

void getans(int l,int r){
	if(l==r) return;
	int mid=l+r>>1;
	int len=r-l+1>>1;
	getans(l,mid);
	getans(mid+1,r);
	if(a[l+len]<a[l]){
		ans++;
		std::swap(a[l],a[l+len]);
	}
	if(a[l]+len!=a[l+len]) flag=true;
}

int main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	std::cin>>t;
	while(t--){
		std::cin>>n;
		flag=false;
		ans=0;
		for(int i=1;i<=n;i++){
			std::cin>>a[i];
		}
		getans(1,n);
		if(flag) std::cout<<-1<<'\n';
		else std::cout<<ans<<'\n';
	}
	return 0;
}

E. Sending a Sequence Over the Network

对于一个数组a,我们可以把它划分为若干段,例如a=[1,2,3,1,2,3],我们可以把它划分为[1],[2,3,1],[2,3]三段,将他们和他们的长度重新组合,要求每段长度可以在这一段左侧或是右侧,这样对于一个相同的划分方式,最后得到的可能有若干种结果。现给出这个最终结果,判断是否存在一个原数组,使得操作后成为现在给出的数组。

思路:对于可行性进行DP。定义f[i]为前i个数是否存在合法序列,对于每一个数a[i],都有可能是某一段的最左侧数字或最右侧数字,分情况即可。

AC Code:

#include <bits/stdc++.h>

typedef long long ll;
const int N=2e5+5;
int t,n;
int a[N],f[N];

int main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	std::cin>>t;
	while(t--){
		std::cin>>n;
		for(int i=1;i<=n;i++){
			std::cin>>a[i];
			f[i]=0;
		}
		f[0]=1;
		for(int i=1;i<=n;i++){
			if(i+a[i]<=n)
				f[i+a[i]]|=f[i-1];
			if(i>=a[i]+1)
				f[i]|=f[i-a[i]-1];
		}
		if(f[n]) std::cout<<"YES"<<'\n';
		else std::cout<<"NO"<<'\n';
	}
	return 0;
}

F. Multi-Colored Segments

待补。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值