Codeforces Round #643 (Div. 2)(A-D题解)

感觉每次自己没赶上的比赛vitural做起来都格外的顺手.每次赶上的都做的格外难受:(
这场的A-D都比较简单.
A.Sequence with Digits
题目大意:定义了一种关系an+1 = an + maxdig(an)*mindig(an).这里的max和min指的是十进制下an的最大的数和最小的数.给了a1和k求ak.
因为迟早会出现0.这个时候就不会改变了.所以暴力的做就好了.

#pragma GCC optimize(2)
#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<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#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 t;
LL solve(LL x){
	LL m1 = -1,m2 = 10;
	while(x){
		m1 = max(m1,x%10);
		m2 = min(m2,x%10);
		x/=10;
	}
	return m1*m2;
}
int main(){
	cin >> t;
	while(t--){
		LL a,k;
		cin >> a >> k;
		--k;
		if(k == 0){
			cout << a << endl;
			continue;
		}
		while(1){
			LL tmp = solve(a);
			--k;
			if(!tmp || k == 0){
				cout << a+tmp << endl;
				break;
			}
			else a += tmp;
		}
	}
	
	return 0;
}

B - Young Explorers
题目大意:洛谷上面的一道题.
排个序然后dp.dp[i]表示把当前i到[1,i-a[i]]分成一组时能组成的最大组数.如果暴力的维护的话是O(n2)的.可以用一个f[i]维护1,i里面最大的dp[i]复杂度就降到了O(n).网上的贪心题解可能有些是错的…具体可以看洛谷里的讨论.一大堆贪心里只有一个人是对的…
代码

#pragma GCC optimize(2)
#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<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#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],dp[N],f[N];
int main(){
	int t;
	cin >> t;
	while(t--){
		int n;
		cin >> n;
		fir(i,1,n) cin >> a[i],dp[i] = 0;
		sort(a+1,a+1+n);
		int ans = 0;
		fir(i,1,n){
			if(i >= a[i]){
				dp[i] = dp[f[i-a[i]]] + 1;
				if(dp[i] > dp[f[i-1]]) f[i] = i;
				else f[i] = f[i-1];
			}
			else dp[i] = 0;
			ans = max(ans,dp[i]);
		}
		cout << ans << endl;
	}
	
	return 0;
}

C - Count Triangles
题目大意:给A,B,C,D四个数,x在[A,B],y在[B,C],z在[C,D]问能组成多少个三角形.
因为xyz本身就是有序的.三角形判定定理:最小的两条边和大于第三边.那x+y范围就是[A+B,B+C]里面.这里面每个数的个数可以用差分数组统计.然后问题就变成了[C,D]里面大于C,大于C+1,大于C+2…的数有多少个.前缀和减一下答案就出来了,不过要记得数组开大一点.(开小了RE了一发).

#pragma GCC optimize(2)
#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<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#include <bits/stdc++.h>
 
using namespace std;
const int N = 5e6+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;
}
 
LL d[N];
int main(){
	int A,B,C,D;
	LL ans = 0;
	cin >> A >> B >> C >> D;
	fir(i,A,B){
		d[i+B] += 1;
		d[i+C+1] -= 1;
	}
	fir(i,1,N-1) d[i] += d[i-1];
	fir(i,1,N-1) d[i] += d[i-1];
	fir(i,C,D){
		ans += d[B+C] - d[i];
	}
	cout << ans;
	
	return 0;
}

D - Game With Array
题目大意:能否构造一个长度为N和为S的序列让它的子区间和不等于K或者N-K.S>=K>=0.
cf很喜欢出构造题.想不到的话真的做起来很痛苦.这题还算比较简单的构造.其实问题就是让我们让子区间的值尽量的少.那全部用1去构造就ok了.最后一个数用sum-n+1构造.值域就是1,2…n-1,sum-n+1,sum-n+2…sum.然后看中间有没有空出来的数就可以了.

#pragma GCC optimize(2)
#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<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#include <bits/stdc++.h>
 
using namespace std;
const int N = 1e6+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[N];
int main(){
	int n,sum;
	cin >> n >> sum;
	fir(i,1,n-1){
		ans[i] = 1;
	}
	ans[n] = sum-n+1;
	if(ans[n]-n+1 <= 1){
		puts("NO");
		return 0;
	}
	puts("YES");
	fir(i,1,n) cout << ans[i] << " ";
	puts("");
	cout << ans[n]-1;
	
	return 0;
}	

猜你喜欢

转载自blog.csdn.net/weixin_45590210/article/details/106224666