codeforce #642 div3

$A. Most Unstable Array$

$solution$

给定$n,m$,要构造一个长度为$n$的数组,和为$m$,求$\sum_{i=1}^{n-1}\left|a_{i}-a_{i+1}\right|$最大

长度为$1$是$0$,为$2$是$m$,其他是$2\times m$

$code$

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define fi first
#define se second 
#define ll long long
#define pb push_back
typedef pair<long long,long long> pll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<long long> vll;
typedef double db;
const ll mod=1e9+7;
ll powmod(ll a,ll b,ll p){ll res=1;a%=p;while(b){if(b&1) res=res*a%p;a=a*a%p;b>>=1;}return res;}
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
int _;

int main(){
    for(scanf("%d",&_);_;_--){
         int n,k;
         scanf("%d%d",&n,&k);
         if(n==1) {puts("0");}
         else if(n==2) {printf("%d\n",k);}
         else{
            printf("%d\n",k*2);
         }
    }
}

$B. Two Arrays And Swaps$

$solution$

给定两个长$n,1<=n<=30$的数组$a,b$,给定一个$k$,可以将$a$中$k$个替换成$b$中元素,求得最大的和

排序后双指针两个分别从最大最小判断即可 

$code$

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define fi first
#define se second 
#define ll long long
#define pb push_back
typedef pair<long long,long long> pll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<long long> vll;
typedef double db;
const ll mod=1e9+7;
ll powmod(ll a,ll b,ll p){ll res=1;a%=p;while(b){if(b&1) res=res*a%p;a=a*a%p;b>>=1;}return res;}
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
int _;
const int N=50;
int a[N],b[N];

int main(){
    for(scanf("%d",&_);_;_--){
        int n,k;
        cin>>n>>k;

        rep(i,0,n) cin>>a[i];
        rep(i,0,n) cin>>b[i];

        sort(a,a+n);
        sort(b,b+n);

        int ans=0;
        for(int i=0,j=n-1;i<n;i++,j--) {
            if(a[i]<b[j] && k){ans+=b[j];k--;}
            else ans+=a[i];
        }
        printf("%d\n",ans);
            
    }
}

$C. Board Moves$

$solution$

$n \times n, n$(是奇数) 的矩阵,初始每个格子都有$1$个东西,八相邻方向移动算一步,将所有的移动到一个格子要多少步

因为是奇数所以有正中心,从中间向外扩计算即可 

$code$

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define fi first
#define se second 
#define ll long long
#define pb push_back
typedef pair<long long,long long> pll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<long long> vll;
typedef double db;
const ll mod=1e9+7;
ll powmod(ll a,ll b,ll p){ll res=1;a%=p;while(b){if(b&1) res=res*a%p;a=a*a%p;b>>=1;}return res;}
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
int _;

int main(){
    for(scanf("%d",&_);_;_--){
        ll n;
        cin>>n;
        if(n==1){puts("0");continue;}
        n/=2;
        ll ans=0;
        for(ll i=1;i<=n;i++){
            ans+=i*8*i;
        }
        cout<<ans<<endl;
    }
} 

$D. Constructing the Array$

$solution$

给定长度为$n,1<=n<=2 \times 10^{5}$的全0数组,选取长度最大的,长度相等的选取最靠做的连续子区间$[l,r]$

一个操作变量初始为1,如果区间长度为偶数,就将数组$(l+r-1)/2$位置上值改成这个变量

奇数就在$(l+r)/2$位置上记录,因为区间没有重叠,优先队列,重载比较函数,长度大的优先,相等左边小的优先

$code$

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define fi first
#define se second 
#define ll long long
#define pb push_back
typedef pair<long long,long long> pll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<long long> vll;
typedef double db;
const ll mod=1e9+7;
ll powmod(ll a,ll b,ll p){ll res=1;a%=p;while(b){if(b&1) res=res*a%p;a=a*a%p;b>>=1;}return res;}
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
int _;
const int N=2e5+10;
struct node{
    int x,y;
    bool operator <(const node &b) const{
        if(x == b.x)
            return y > b.y;
        return x<b.x;
    }
};
int main(){
    for(scanf("%d",&_);_;_--){
        int n;
        cin>>n;
        vi res(n+1);
        priority_queue<node> seg;
        int l=1,r=n;
        int now=1;
        seg.push({r-l+1,l});
        while(seg.size()){
            auto t=seg.top();
            seg.pop();
            if(t.x!=0){
                r=t.y+t.x-1;
                l=t.y;
                int mid;
                if((r-l+1)%2==0) {
                        res[(l+r-1)/2]=now;
                        mid=(l+r-1)/2;
                    }
                else {
                    res[(l+r)/2]=now;
                    mid=(l+r)/2;
                }
                now++;
                if(mid-1-l+1 != 0) seg.push({mid-1-l+1,l});
                if(r-(mid+1)+1 !=0) seg.push({r-(mid+1)+1,mid+1});
            }
        }
        for(int i=1;i<=n;i++) cout<<res[i]<<' ';
        puts("");
    }
}

$E. K-periodic Garland$

$solution$

$code$

$F. Decreasing Heights$

$solution$

$code$

猜你喜欢

转载自www.cnblogs.com/hhyx/p/12892477.html