CF1515

CF1515

A:CF1515A Phoenix and Gold

因为所有数并不相同,所以这个题解决起来很简单,如果前缀和 \(ans=x\) 时,交换前后两个数位置就行了,其他的正常输出。

#include<bits/stdc++.h>
using namespace std;
int T,n,x;
const int N=1e2+5;
int a[N];
int main(){
    cin>>T;
    while(T--){
        cin>>n>>x; int ans=0,flag=0;
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),ans+=a[i]; 
        if(ans==x){puts("NO"); continue;}
        puts("YES"); ans=0;
        for(int i=1;i<=n;i++){
            ans+=a[i];
            if(ans==x){
                swap(a[i],a[i+1]);
                printf("%d %d ",a[i],a[i+1]); ans+=a[i];
                i++; continue;
            }
            printf("%d ",a[i]);
        }
        puts("");
    }
    // system("pause");
    return 0;
}

B:CF1515B Phoenix and Puzzle

考虑一下怎么可以构成一个正方形:当两个或者四个相同等腰直角三角形可以组成。

而且这两种组合方法不能同时用。

因此必须 \(\frac{n}{2}\)\(\frac{n}{4}\) 是完全平方数才行。

判断一下即可。

#include<bits/stdc++.h>
using namespace std;
int T,n;
bool check(int x){
    if(sqrt(x)*sqrt(x)==x) return 1;
    return 0;
}
int main(){
    cin>>T;
    while(T--){
        cin>>n;
        if(check(n/2)||check(n/4)) puts("YES");
        else puts("NO");
    }
    return 0;
}

C:CF1515C Phoenix and Towers

贪心问题,我们遍历 \(n\) 个数字, 每次把当前这个数字放到总和最小的组里即可.

因为我们最后要求任意两组之前的差值尽可能的小, 相当于让 \(m\) 组数尽可能的平均. 我们贪心去做即可(从大到小一个一个放).

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N=1e5+10;
int res[N],n,m,k,T;
int main()
{
	cin>>T;
	while(T--){
        priority_queue<PII, vector<PII>, greater<>>q;//放里面西巴
		scanf("%d %d %d", &n, &m, &k); 
        for(int i=1;i<=m;i++) q.push({0,i}); //第二维是组数的下标
		for(int i=1,x;i<=n;i++){
			scanf("%d", &x);
			auto op=q.top(); q.pop();
			op.first+=x; res[i]=op.second;
			q.push(op);
		}
		puts("YES");
		for(int i=1;i<=n;i++) printf("%d ",res[i]); puts("");
	}
    // system("pause");
	return 0;
}

D:CF1515D Phoenix and Socks

依然是贪心。

对于所有能匹配的情况,我们肯定能匹配就匹配。(大废话)

设对于左右不同颜色的直接匹配为硬匹配,花费 \(2\) 元。

不花钱的处理完了之后,若存在 \(L != R\) 的情况,此时不能直接硬匹配。

如果 \(L\) 多,就在 \([1,L]\) 中找找,能不能改方向,不改颜色匹配。

因为此时硬匹配不但要改颜色而且要改方向,不如先在L中看看能不能同方向匹配,能的话绝对是赚的,每匹配一对,最终少改一次颜色.

最后剩下的只能硬匹配了

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,T,l,r,a[N],col[N],cor[N];
int main(){
    cin>>T;
    while(T--){
        int finish=0,ans=0;
        cin>>n>>l>>r;
        for(int i=1;i<=n;++i){
            scanf("%d",&a[i]);
            if(i<=l) col[a[i]]++;
            else cor[a[i]]++;
        }
        int nl=l,nr=r;
        for(int i=1;i<=l;++i){//处理左右匹配
            if(col[a[i]]&&cor[a[i]]){
                col[a[i]]--; cor[a[i]]--;
                nl--; nr--;
            }
        }
        if(nl>=nr){
            for(int i=1;i<=l;++i)//处理左匹配
                if(col[a[i]]>=2&&nl>nr){
                    col[a[i]]-=2;
                    nl-=2; ans++;
                }
            ans+=(nl-nr)/2+(nl+nr)/2;
        }
        else {//处理右匹配
            for(int i=l+1;i<=n;++i)
                if(cor[a[i]]>=2&&nr>nl){
                    cor[a[i]]-=2;
                    nr-=2; ans++;
                }
            ans+=(nr-nl)/2+(nr+nl)/2;
        }
        cout<<ans<<endl ;
        for(int i=1;i<=n;++i) col[i]=cor[i]=0;
    }
    return 0;
}
posted @ 2021-09-16 21:44  Evitagen  阅读(35)  评论(0编辑  收藏  举报