Educational Codeforces Round 145 (Rated for Div. 2) A-D

比赛链接:Dashboard - Educational Codeforces Round 145 (Rated for Div. 2) - Codeforces

A:结论题Educational Codeforces Round 145 (Rated for Div. 2) A-D_第1张图片Educational Codeforces Round 145 (Rated for Div. 2) A-D_第2张图片

题意:给你 4 个拥有颜色的灯,你可关闭或打开这个灯当且仅当你上次关闭或打开的灯的颜色与当前灯的颜色不同,问将其都打开的操作次数。 

分析:手撸样例直接得结论

1:如果是四盏颜色相同的等,输出-1

2:如果相同颜色的灯的个数为3,则需要操作6次

3:否则操作4次

代码:

#include 
#define pi acos(-1)
#define int long long
#define PII pair
#define all(v) v.begin(),v.end()
#define INF 0x3f3f3f3f3f3f3f3f
#define fs(a) cout<>=1;}return ans;}//快速幂
int qc(int a,int b,int p){int ans=0;while(b){if(b&1){ans+=a,ans%=p;}a*=2;a%=p;b>>=1;}return ans;}//快速乘 a*b%p

inline void solve(){
	string s;cin>>s;
	mapmp;int cnt=0;
	for(int i=0;i>T;
	while(T--) solve();
}              

B:思维(规律)

Educational Codeforces Round 145 (Rated for Div. 2) A-D_第3张图片

Educational Codeforces Round 145 (Rated for Div. 2) A-D_第4张图片

题意:给定个n个点,叫你在直角坐标系中放置点位,使其各个点之间的距离大于1,且每个点对答案的影响为|x|+|y|。求最小的ans.(ans=max((|x_{1}]+|y_{1}),....,(|x_{n}|+|y_{n}|))

分析:我们发现,如果需要放置2个点,放在边长为1的正方形的对角线位置,所得的距离为根号2是大于1的。然后根据这个思想,可以绘制一张图得到一个规律。在平面中放n个点 (xi,yi) ,使得任意两个点之间的欧式距离大于1 ,其放置一个点的代价是 |xi|+|yi| ,求一种代价最小的放法并输出这个价值

图解:Educational Codeforces Round 145 (Rated for Div. 2) A-D_第5张图片

结论:n是平方数,就是sqrt(n)-1.else sqtr(n)

代码:

#include 
#define pi acos(-1)
#define int long long
#define PII pair
#define all(v) v.begin(),v.end()
#define INF 0x3f3f3f3f3f3f3f3f
#define fs(a) cout<>=1;}return ans;}//快速幂
int qc(int a,int b,int p){int ans=0;while(b){if(b&1){ans+=a,ans%=p;}a*=2;a%=p;b>>=1;}return ans;}//快速乘 a*b%p

inline void solve(){
	int n;cin>>n;
	int ans=0,m=sqrt(n);
	if(m*m==n) cout<>T;
	while(T--) solve();
}              

C:构造

Educational Codeforces Round 145 (Rated for Div. 2) A-D_第6张图片

Educational Codeforces Round 145 (Rated for Div. 2) A-D_第7张图片

题意:构造一个长度为N,恰好有k个子序列的元素和为正数,其余的子序列元素之和为负数的整数序列

分析:

思路:放连续x个正数后,再放连续y个负数,使其满足条件。

解释:我们发现,N个连续的正数,其能产生\frac{n\cdot (n+1)}{2}个正和序列。这里所采用的构造方法很有意思。我们找到一个最大X,因为连续x个正数能够产生M=\frac{x\cdot (x+1)}{2}个正和序列。当M\leq K时,我们找到了最大的X。因此,我们放置x个连续的正数。(这里正数任取,都放相同的正数最简单)。再放N-X个负数

1:K=M,那么就放X个正数即可

2:否则就考虑放负数的情况。

2--->:我们令Q=K-M,为还需要补充的正数和序列的个数(就是放置X个正数后,放完了负数,如何调整使得再多产生Q个正数序列)。

构造方法(图解):

Educational Codeforces Round 145 (Rated for Div. 2) A-D_第8张图片

为什么?我们将第一个负数调小,将第 k 个正数调大即可(这里可能有点难懂,别急,接着往下看)Educational Codeforces Round 145 (Rated for Div. 2) A-D_第9张图片

 ps:C题是一道非常有意思的构造,其思维很奇特,建议读者细品。

 D:贪心Educational Codeforces Round 145 (Rated for Div. 2) A-D_第10张图片

Educational Codeforces Round 145 (Rated for Div. 2) A-D_第11张图片题意:给定一个 01 串,进行交换 01 操作或删除操作,使串变为不存在递减的串交换花费 10^12,删除花费 10^12+1,求最小花费。

分析:贪心策略。挺容易想到的。

答案肯定行如左半部分全为 0,右半部分全为 1。

我们可以枚举 0,1 的分界点,那么此时将分界点以左的 1 全部删去,以右的 0 全部删去。

此时,若 1,0 与分界点相邻可以省去两次删除操作,使用交换操作。

因此,预处理前缀 1 的个数,与后缀 0 的个数,随后枚举即可。

代码:

#include 
#define pi acos(-1)
#define int long long
#define PII pair
#define all(v) v.begin(),v.end()
#define INF 0x3f3f3f3f3f3f3f3f
#define fs(a) cout<>=1;}return ans;}//快速幂
int qc(int a,int b,int p){int ans=0;while(b){if(b&1){ans+=a,ans%=p;}a*=2;a%=p;b>>=1;}return ans;}//快速乘 a*b%p

inline void solve(){
	string s;cin>>s;
	mappre,ne;
	for(int i=0;i=0;i--){
		ne[i]=ne[i+1];
		if(s[i]=='0') ne[i]++;
	}
	int ans=INF;
	for(int i=0;i<=s.size();i++){
		int change=pre[i-1]+ne[i];
		ans=min(ans,change*(int)(1e12+1));
		if(i!=0&&i!=s.size()){
			if(s[i]=='0'&&s[i-1]=='1') ans=min(ans,(change-2)*(int)(1e12+1)+(int)1e12);
		}
	}
	cout<>T;
	while(T--) solve();
}              

 

你可能感兴趣的:(Codeforces,Contest,c++,算法,codeforces)