Codeforces Round 886 (Div. 4)

 

目录

D. Balanced Round

E. Cardboard for Pictures

F. We Were Both Children

G. The Morning Star

H. The Third Letter


D. Balanced Round

题意:给定数组,可以从中删去一定的数字,要求删去后的数组任意两数之间的绝对值之差不大于k。

思路:题目要我们先删除,但先排序后删除本质上是一样的,所以先将数组进行排序,由此,此题转话为了在有序数组中寻找最大的一段符合条件的的区间,即区间中后一个数减前一个的差不能超过k,因为题目要求剩余区间全部合法,所以我们只用求出最大合法区间,然后把其他的全部删去就好。

#include

using namespace std;
const int N=1e5+5;
typedef long long ll;
typedef pair pll;
int mod=998244353;
const int maxv=4e6+5;

ll qmi(int a,int b)
{
    ll res=1;
    while(b){
        if(b%2) res*=b%mod;
        b>>=1;
        a=a*a%mod;
    }
    return res;
}

ll inv(int x)
{
    return qmi(x,mod-2);
}


int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};

void solve()
{	
	int n,k;
	cin>>n>>k;
	vector a(n+5);
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a.begin()+1,a.begin()+1+n);
	int cnt=1;
	int res=0;
	for(int i=1;i>t;
	while(t--){
		solve();
	}
	system("pause");
	return 0;
}

E. Cardboard for Pictures

题意,给定总面积s,然后给定每个正方形的面积,现给每个正方形的外圈裱一层w长的外圈,求让所有正方形裱完后的面积总和等于s的w。

思路:题意被我描述的可能有点抽象,但思路就是去二分答案,容易知道,w是具有单调性的,即w越大,最后的面积总和也一定越大,所有可以去二分去解决。

#include

using namespace std;
const int N=2e5+5;
typedef long long ll;
typedef pair pll;
int mod=998244353;
const int maxv=4e6+5;

ll qmi(int a,int b)
{
    ll res=1;
    while(b){
        if(b%2) res*=b%mod;
        b>>=1;
        a=a*a%mod;
    }
    return res;
}

ll inv(int x)
{
    return qmi(x,mod-2);
}

ll n,c;
vector s(N);

bool check(ll x)
{
	ll sum=0;
	for(int i=1;i<=n;i++){
		ll m=(s[i]+x*2)*(s[i]+x*2);
		sum+=m;
		if(sum>c) return false;
	}
	return true;
}

void solve()
{	
	cin>>n>>c;
	for(int i=1;i<=n;i++) cin>>s[i];
	ll l=0,r=1e9;
	ll ans=0;
	while(l<=r){
		ll mid=(l+r)/2;
		if(check(mid)){
			l=mid+1;
			ans=mid;
		}
		else{
			r=mid-1;
		}
	}
	cout<>t;
	while(t--){
		solve();
	}
	system("pause");
	return 0;
}

F. We Were Both Children

题意:给定数组,让我们求1-n中的某个数,为数组中某些数字的倍数,且数组元素个数最大。

思路:一开始初看题意以为考察的是lcm,结果一细想是分解因数。一开始考虑的是数组中每个元素因子在数组中的出现次数,后面再细想应该是求1-n中的每个数字的因子在数组中的出现次数。

#include

using namespace std;
const int N=2e5+5;
typedef long long ll;
typedef pair pll;
int mod=998244353;
const int maxv=4e6+5;

ll qmi(int a,int b)
{
    ll res=1;
    while(b){
        if(b%2) res*=b%mod;
        b>>=1;
        a=a*a%mod;
    }
    return res;
}

ll inv(int x)
{
    return qmi(x,mod-2);
}




void solve()
{	
	int n;
	cin>>n;
	map mp;
	for(int i=1;i<=n;i++){
		int x;
		cin>>x;
		mp[x]++;
	}
	int ans =0;
	for(int j=1;j<=n;j++){
		int res=0;
		for(int i=1;i<=j/i;i++){
			if(j%i==0){
				int c1=j/i;
				res+=mp[c1];
				if(i!=j/i) res+=mp[i];
			}

		}
		ans=max(ans,res);
	}
	cout<>t;
	while(t--){
		solve();
	}
	system("pause");
	return 0;
}

G. The Morning Star

题意:给定n个坐标,要求求出符合题意坐标对的数量。

思路:就是和斜率有关的表示吧,开个map存一下x,y,x+y,x-y这四种情况,然后遍历相加即可。

#include

using namespace std;
const int N=2e5+5;
typedef long long ll;
typedef pair pll;
int mod=998244353;
const int maxv=4e6+5;

ll qmi(int a,int b)
{
    ll res=1;
    while(b){
        if(b%2) res*=b%mod;
        b>>=1;
        a=a*a%mod;
    }
    return res;
}

ll inv(int x)
{
    return qmi(x,mod-2);
}




void solve()
{	
	int n;
	cin>>n;
	vector a(n),b(n);
	map x,y,kz,kf;
	for(int i=0;i>a[i]>>b[i];
		x[a[i]]++;
		y[b[i]]++;
		ll c1=a[i]-b[i];
		ll c2=a[i]+b[i];
		ll x=qmi(c1,c2);
		kz[c1]++;
		kf[c2]++;
	}
	ll ans =0;
	for(int i=0;i>t;
	while(t--){
		solve();
	}
	system("pause");
	return 0;
}

H. The Third Letter

题意:给定n个点,m条边,要求判断建成的图是否合法

思路:先建图,然后再去遍历bfs判断是否合法即可。

#include

using namespace std;
const int N=2e5+5;
typedef long long ll;
typedef pair pll;
int mod=998244353;
const int maxv=4e6+5;

ll qmi(int a,int b)
{
    ll res=1;
    while(b){
        if(b%2) res*=b%mod;
        b>>=1;
        a=a*a%mod;
    }
    return res;
}

ll inv(int x)
{
    return qmi(x,mod-2);
}

ll d[N];
int st[N];
vector e[N];
void add(int a,int b,int w)
{
	e[a].push_back({b,w});
}
const ll inf=10000000000;

void solve()
{	

	int n,m;
	cin>>n>>m;
	fill(d,d+n+1,inf);
	for(int i=1;i<=n;i++) e[i].clear();
	for(int i=1;i<=m;i++){
		int a,b,w;
		cin>>a>>b>>w;
		add(a,b,w);//建图
		add(b,a,-w);//无向边要减2条,注意反向的权值
	}
	for(int i=1;i<=n;i++){
		if(d[i]!=inf) continue;//di不等于inf则表示当前已经遍历过该点了
		queue q;
		q.push(i);//不然的话为一个新的连通块
		d[i]=0;//赋值为0
		while(!q.empty()){//bfs遍历过程
			int t=q.front();
			q.pop();
			for(auto [x,y]: e[t]){
				if(d[x]==inf){//如果当前点还没有被遍历到,就更新当前点的距离
					d[x]=d[t]+y;
					q.push(x);
				}
				else{
					if(d[x]!=y+d[t]){//不然的话就去判断当前点的距离是否合法
						cout<<"NO"<>t;
	while(t--){
		solve();
	}
	system("pause");
	return 0;
}

你可能感兴趣的:(cf补题,算法)