Codeforces Round #690 (Div. 3) 题解

A. Favorite Sequence
模拟题
代码

#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>

using namespace std;
const int N = 2e5+10;

inline int read(){
	int x = 0,f=1;char ch = getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

int a[N];
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t;
	cin >> t;
	while(t--){
		int n;
		cin >> n;
		fir(i,1,n) cin >> a[i];
		int i = 1,j = n;
		while(i <= j){
			if(i == j) cout << a[i++] << ' ';
			else cout << a[i++] << " " << a[j--] << " ";
		}
		cout << "\n";
	}
	
	return 0;
}	

B. Last Year’s Substring
就枚举头尾有没有:
2020xxx
2xxx020
20xxx20
202xxx0
xxx2020
就ok了
代码:

#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>

using namespace std;
const int N = 2e5+10;

inline int read(){
	int x = 0,f=1;char ch = getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
string str = "2020";
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t;
	cin >> t;
	while(t--){
		int n;
		cin >> n;
		string s;
		cin >> s;
		s  = ' ' + s;
		bool f = 0;
		fir(k,0,4){
			bool ff = 1;
			fir(i,1	,k){
				if(s[i] != str[i-1]){
					ff = 0;
					break;
				}
			}
			int kk = 4-k;
			fir(i,0,kk-1){
				if(str[3-i] != s[n-i]){
					ff = 0;
					break;
				}
			}
			if(ff){
				f = 1;
				break;
			}
		}
		if(f) cout << "YES\n";
		else cout << "NO\n";
	}
	
	return 0;
}	

C. Unique Number
dfs瞎搞或者直接打表就好了(找不到当时打表的代码了)

#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>

using namespace std;
const int N = 2e5+10;

inline int read(){
	int x = 0,f=1;char ch = getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int ans[50] = {1
,2
,3
,4
,5
,6
,7
,8
,9
,19
,29
,39
,49
,59
,69
,79
,89
,189
,289
,389
,489
,589
,689
,789
,1789
,2789
,3789
,4789
,5789
,6789
,16789
,26789
,36789
,46789
,56789
,156789
,256789
,356789
,456789
,1456789
,2456789
,3456789
,13456789
,23456789
,123456789
,-1
,-1
,-1
,-1
,-1};
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t;
	cin >> t;
	while(t--){
		int n;
		cin >> n;
		cout << ans[n-1] << "\n";
	}
	
	return 0;
}	

D. Add to Neighbour and Remove
枚举一下最后数组的长度,如果数组的和sum%len==0,那么这个len就有机会成为答案.具体做法就是得到平均值avg=sum/len后遍历数组如果avg>a[i]就不可以,如果是a[i]<avg就贪心的直接累加到右边,因为它一定要增大,这个时候增大的幅度是最小的.
代码

#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>

using namespace std;
const int N = 2e5+10;

inline int read(){
	int x = 0,f=1;char ch = getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

int a[N],b[N];
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t;
	cin >> t;
	while(t--){
		int n,sum=0;
		cin >> n;
		fir(i,1,n) cin >> b[i],sum+=b[i];
		int f = -1;
		afir(len,n,1){
			int avg = sum%len;
			if(avg) continue;
            avg = sum/len;
			bool ff = 1;
			fir(i,1,n) a[i] =b[i];
			fir(i,1,n){
				if(a[i] > avg){
					ff = 0;
					break;
				}
				if(a[i] < avg){
					if(i!=n) a[i+1] += a[i];
					else{
						ff = 0;
						break;
					}
				}
			}
			if(ff){
				f = n-len;
				break;
			}
		}
		cout << f << '\n';
	}
	
	return 0;
}	

E1. Close Tuples (easy version)
E2. Close Tuples (hard version)
直接考虑E2.翻译一下题目:从大小为n的数组中选出m个元素,问能选出多少个序列中max-min<=k的有序对.
可以直接排序,然后二分出最后一个小于等于a[i]-k的位置pos,然后用组合数学的知识可以知道选i的方案数是C(i-pos,m-1).累加起来即可
代码:

#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>

using namespace std;
const int N = 2e5+10;

inline int read(){
	int x = 0,f=1;char ch = getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

const LL mo=1e9+7;
LL C(LL n,LL m){
	static LL M=0,inv[N],mul[N],invMul[N];
	while(M<=n){
		if(M){
			inv[M]=M==1?1:(mo-mo/M)*inv[mo%M]%mo;
			mul[M]=mul[M-1]*M%mo;
			invMul[M]=invMul[M-1]*inv[M]%mo;
		}
		else mul[M]=1,invMul[M]=1;
		M++;
	}
	return mul[n]*invMul[m]%mo*invMul[n-m]%mo;
}
int a[N];
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t;
	cin >> t;
	while(t--){
		int n,m,k;
		cin >> n >> m >> k;
		fir(i,1,n) cin >> a[i];
		sort(a+1,a+1+n);
		LL ans = 0;
		afir(i,n,1){
			int p = upper_bound(a+1,a+1+n,a[i]-k-1) - a;
			int num = i-p;
			if(num < m-1) continue;
			ans = (ans + C(num,m-1))%mo;
		}
		cout << ans << "\n";
	}
	
	return 0;
}	

F. The Treasure of The Segments
这题细节比较麻烦.思路应该不难.
把题目转换一下,删掉最少区间的意思就是找到每个区间最多和多少个区间相交num[i],答案就是max(n-num[i]).
考虑按区间的右边界排序,然后顺序循环找到当前区间i左边界前面有多少个前面区间的右边界.然后再逆序循环看区间i后面有多少个区间的左边界打到[ l[i],r[i] ]上,这个过程可以用树状数组维护一下.
注意一下排序的时候右边界相同的时候左边界大的要在前面,可以画图理解一下.

#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>

using namespace std;
const int N = 2e6+10;

inline int read(){
	int x = 0,f=1;char ch = getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

vi all;
int getpos(int x){
	return lower_bound(ALL(all),x) - all.begin();
}
pii p[N];
int c[N],n,num[N],tn;
void add(int p,int v){
	for(;p<=tn;p+=p&-p) c[p] += v;
}
int ask(int p){
	int res = 0;
	for(;p;p-=p&-p) res += c[p];
	return res;
}
bool cmp(pii a,pii b){
	return a.ft==b.ft?a.sd>b.sd:a.ft<b.ft;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t;
	cin >> t;
	while(t--){
		all.clear();
		all.pb(INT_MIN);
		cin >> n;
		fir(i,1,n) cin >> p[i].sd >> p[i].ft,all.pb(p[i].ft),all.pb(p[i].sd),all.pb(p[i].ft+1),all.pb(p[i].sd+1);
		sort(p+1,p+1+n,cmp);
		sort(ALL(all));
		all.erase(unique(ALL(all)),all.end());
		tn = all.size()-1;
		fir(i,1,n){
			int pos = lower_bound(p+1,p+1+n,mpr(p[i].sd,0))-p;
			pos--;
			num[i] += i-pos;
		}
		afir(i,n,1){
			p[i].ft = getpos(p[i].ft);
			p[i].sd = getpos(p[i].sd);
			num[i] += ask(p[i].ft)-ask(p[i].sd-1);
			add(p[i].sd,1);
		}
		int ans = INT_MAX;
		fir(i,1,n) ans = min(ans,n-num[i]);
		cout << ans << "\n";
		fir(i,1,n) add(p[i].sd,-1),num[i] = 0;
	}
	
	return 0;
}	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值