Codeforces Global Round 14 ABCDE题解


不好意思先睡了 晚安

A - Phoenix and Gold

题目链接
构造?
先从小到大排序 要是前面的数字加起来刚好等于x, 那我们就交换这个数和后面的那个数 这样保证不会再加起来等于x一定大于
但是不能从大到小排序,因为交换了总和变比 x x x小,然后继续加可能又等于 x x x

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int N = 105;
ll t, n, m, x, a[N], sum[N], cnt, q;
int main() {
    cin>>t;
    while(t--) {
        cin>>n>>x;
        for(int i=1; i<=n; i++) {
            cin>>a[i];
            cnt+=a[i];
        }
        int flag=1;
        cnt=q=0;
        memset(sum, 0, sizeof sum);
        sort(a+1, a+1+n);
        for(int i=1; i<=n; i++) {
            sum[i]=sum[i-1]+a[i];
            if(sum[i]==x) {
                for(int j=i+1; j<=n; j++) {
                    if(a[j]!=a[i]) {
                        //cout<<sum[i]<<" "<<i<<" "<<j<<endl;
                        swap(a[j], a[i]);
                        q++;
                        break;
                    }
                }
                if(q==0) {
                    flag=0;
                    break;
                }else break;
            }
        }
        if(cnt==x) flag=0;
        if(flag==0) cout<<"NO"<<endl;
        else {
            cout<<"YES"<<endl;
            for(int i=1; i<=n; i++) {
                cout<<a[i]<<" \n"[i==n];
            }
        }
    }
    return 0;
}

B - Phoenix and Puzzle

题目链接 题意:给你一个数 n n n问你能不能由 n n n个等腰三角形构成一个正方形
想法
反正正方形是由平方数个的由两个组成或者由四个组成的小正方形组成

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int N = 105;
ll t, n, m, x, a[N], sum[N], cnt, q;
int main() {
    cin>>t;
    while(t--) {
        cin>>n;
        if(n%2==1) cout<<"NO"<<endl;
        else {
            x=n;
            while(n%2==0) n/=2;
            q=sqrt(n);
            if(q*q==n) cout<<"YES"<<endl;
            else {
                n=x;
                while(x%4==0) x/=4;
                q=sqrt(n);
                if(q*q==n) cout<<"YES"<<endl;
                else cout<<"NO"<<endl;
            }
        }
    }
    return 0;
}

C - Phoenix and Towers

题目链接 题意:给你 n n n个小积木搭成 m m m个塔使各个塔之间的高度差不超过 x x x
贪心/优先队列
把塔的高度用优先队列维护, 每次取头,就是取高度最小的那个,把积木给他,最后任意两个塔的差值一定再 x x x之内 最后使一定能保证的 所以没有 N O NO NO

#include <bits/stdc++.h>
using namespace std;
typedef  long long ll;
typedef  pair<ll, ll> pi;
const int N = 100005;
ll t, n, m, k, a[N], sum[N], cnt, x;
priority_queue<pi, vector<pi>, greater<pi>>q;
int main() {
    cin>>t;
    while (t--) {
        cin>>n>>m>>k;
        while (!q.empty()) q.pop();
        for (int i=1; i<=m; i++) q.push({0, i});
        cout<<"YES"<<endl;
        for (int i=1; i<=n; i++) {
            cin>>x;
            pi now=q.top();
            q.pop();
            cout<<now.second<<" ";
            q.push({ now.first+x, now.second });
        }
        cout<<endl;
    }
    return 0;
}

D - Phoenix and Socks

题目链接
模拟
纯模拟
要是左边袜子多然后颜色相同 那么我们就转换为右袜子。。。。

#include<bits/stdc++.h>
using namespace std;
const int N=200005;
#define ll long long
int t, n, l, r, sum, ans, q, k, a[N], b[N], c[N], d[N];
int main(){
	cin>>t;
	while(t--){
		memset(c, 0, sizeof c);
		memset(d, 0, sizeof d);
		cin>>n>>l>>r;
		for(int i=1; i<=l; i++) {
            cin>>a[i];
            c[a[i]]++;
		}
		for(int i=1; i<=r; i++) {
            cin>>b[i];
            d[b[i]]++;
		}
		ans=0;
		if(l>=r){
			for(int i=1; i<=n; i++) {//枚举袜子颜色, 因为题目说颜色不超过n
				if(c[i]>d[i]){
					k=min((c[i]-d[i])/2, (l-r)/2);
					ans+=k;
					c[i]-=k, d[i]+=k;
					l-=k, r+=k;
				}
			}
			for(int i=1; i<=n; i++) {
				if(c[i]>d[i]) {
					k=min((c[i]-d[i]), (l-r));
					ans+=k;
					c[i]-=k, d[i]+=k;
					l-=k, r+=k;
				}
			}
			sum=0;
			for(int i=1; i<=n; i++) {
				sum+=abs(c[i]-d[i]);
			}
			ans+=sum/2;
		}else {
			ans=0;
			for(int i=1; i<=n; i++) {
				if(d[i]>c[i]){
					k=min((d[i]-c[i])/2, (r-l)/2);
					ans+=k;
					d[i]-=k, c[i]+=k;
					l+=k, r-=k;
				}
			}
			for(int i=1; i<=n; i++) {
				if(d[i]>c[i]){
					k=min((d[i]-c[i]), (r-l));
					ans+=k;
					d[i]-=k, c[i]+=k;
					l+=k, r-=k;
				}
			}
			sum=0;
			for(int i=1; i<=n; i++) {
				sum+=abs(c[i]-d[i]);
			}
			ans+=sum/2;
		}
		cout<<ans<<endl;
	}
	return 0;
}

E - Phoenix and Computers

题目链接
d p dp dp
bshd
待补


总结

比赛多走走多想想多画画
别A个两道嘛就下班
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值