Codeforces Round 895补题报告

AC情况

ABCDEFG
ACACTLE(AC)------(AC)------(AC)------------

A  Two Vessels

题意:你有两个容器,一个装有a克水,一个装有b克水,此时你还有个能装c克水的容器,

求使两个容器中的水质量相等所需的最小移动次数

题解:

可以直接计算出倒水的次数:

代码:

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
int main(){
	int n;
	cin>>n;
	while(n--){
		int a,b,c;
		cin>>a>>b>>c;
		int k=abs(a-b);
		int ans=ceil(k/2.0/c);
		cout<<ans<<endl;
	}
	return 0;
}

B The Corridor or There and Back Again

题意:有无限个房间,其中有n个房间,有标号di和陷阱形成的时间si,如果你第t秒到达第i个房间,那么陷阱就会在第t+si秒后激活。

问打印最大的k允许前往房间k然后返回房间1而不会遇到活动陷阱。 

题解:

当si为奇数时,最多可以走到k+\frac{si-1}{2} 个房间

当si为偶数时,最多可以走到  k+floor(\frac{si-1}{2}) 个房间

求出每一个最多可以到达的房间  k+\frac{si-1}{2} ,并不断求出最小值。

代码:

#include <bits/stdc++.h> 
using namespace std;
typedef unsigned long long ull;
int main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		int mn=INT_MAX;
		while(n--){
		   int a,b;
		   cin>>a>>b;
		   int s;
		   s=a+(b-1)/2;
		   mn=min(mn,s);
		}
		cout<<mn<<endl;
	}
	return 0;
}

C Non-coprime Split

题意:有两个整数l和r,找出一对正整数a和b,分别满足以下两种情况:

  • l≤a+b≤r
  • gcd(a,b)≠1

如果不存在就输出-1

题解:

找到一个i,满足(2<=i<=sqrt(r)),定义一个k=r/i,如果k*i>=l,且k>1,则i和(k-1)*i必然是l和r之间

gcd(i,(k-1)*i)=i!=1的符合要求的整数。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
int main(){
	int n;
	cin>>n;
	while(n--){
		int l,r;
		cin>>l>>r;
		bool flag=false;
		for(int i=2;i<=sqrt(r);i++){
			int k=r/i;
			if(k*i>=l&&k>1){
				cout<<i<<" "<<(k-1)*i<<endl;
				flag=true;
				break;
			}
		}
		if(flag==false) cout<<-1<<endl;
	} 
	return 0;
}

gcd的写法 

long long gcd(long long a,long long b){
	while(a^=b^=a^=b%=a);
	return b;
}
long long gcd(long long a,long long b){
	if(a%b==0) return b;
	return gcd(b,a%b);
}

D   Plus Minus Permutation

题意

你有三个整数,n,x,y在,把排列P的得分称为p1.....pn的值,

求(p1⋅x+p2⋅x+…+p⌊nx⌋⋅x)−(p1⋅y+p2⋅y+…+p⌊ny⌋⋅y)的最大值

思路:

使被减数尽可能的大,减数尽可能的小。把大数放到 x 上,小数放到 y上。

最终答案为

ans=\sum x-\sum y

代码:

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
long long gcd(long long a,long long b){
	while(a^=b^=a^=b%=a);
	return b;
}
int main(){
    long long t;
    cin>>t;
    while(t--){
    	long long n,x,y;
    	cin>>n>>x>>y;
    	long long ans=0;
    	long long k=n/(x/gcd(x,y)*y);
    	ans+=(n+n-(n/x-k)+1)*(n/x-k)/2;
    	ans-=(1+(n/y-k))*(n/y-k)/2;
    	cout<<ans<<endl;
	}
	return 0;
}

E Data Structures Fan 

题意:

给定一个长度为 n 的数组和一个长度为 n 的二进制串 s,现有两个操作:

  1. 1 l r,表示将 l≤i≤r 的所有 si​ 取反(00 变 11,11 变 00);
  2. 2 g(∈{0,1})(g∈{0,1}),表示将所有si​=g 的 ai​ 求异或和;

1≤n≤105,1≤t≤104.

思路:

异或的性质:

0^n=n n^0=n n^n=0

用到异或前缀和:s[i]=s[i-1]^a[i];

s0:计算所有si=0的数字ai异或的和

s1:  计算所有si=1的数字ai异或的和

求a[l]到a[r]的异或值:s[r]^s[l-1]

替换:s0^=s[r]^s[l-1]

          s1^=s[r]^s[l-1]

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int a[maxn],s[maxn],ans[maxn];
int main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			s[i]=s[i-1]^a[i];
		}
	    string c;
	    cin>>c;
	    int s1=0,s0=0;
	    for(int i=0;i<c.size();i++){
	    	if(c[i]=='0'){
	    		s0^=a[i+1];
			}
			if(c[i]=='1'){
				s1^=a[i+1]; 
			}
		}
	    int m,o=0;
	    cin>>m;
	    while(m--){
	    	int k;
	    	cin>>k;
	    	if(k==2){
	    		int p;
	    		cin>>p;
	    		if(p==0) ans[++o]=s0;
	    		if(p==1) ans[++o]=s1;
			}
			if(k==1){
				int l,r;
				cin>>l>>r;
				s0^=(s[r]^s[l-1]);
				s1^=(s[r]^s[l-1]);
			}
		}
		for(int i=1;i<=o;i++){
			cout<<ans[i]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

总结 

注重思维能力的提升。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值