Codeforces Round #601 (Div. 2)

Codeforces Round #601 (Div. 2)node

A. Changing Volumeios

题意:有T组数据,每组数据给两个数ab,每次能够对a进行(-5-2-1+1+2+5)操做中的一种,问从a转换为b最少须要多少次。c++

思路:贪心,对ab的差取绝对值,先尽量多的选操做5,再尽量多的选操做2,最后再选操做1 .数组

#include<bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int total,a,b;
    int num[3]={5,2,1};
    cin>>total;
    while(total--){
        cin>>a>>b;
        long long cha=abs(a-b);
        int ans=0;
        if(cha>0){
            for(int i=0;i<3;i++){
                ans+=cha/num[i];
                cha%=num[i];
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

B. Fridge Lockers优化

题目数据范围被修改了,如今改成了m≤n,就很好写了spa

题意:给n个点,让建m条边,要求每一个点至少有2个临边,建边的费用为边的两个顶点之和,问可否建出该图,若是能输出最小建造费用,不然输出-1.code

思路:造成环便可,m<n和n=2时不知足要求。(这是原题目:m>n时的思路和证实:传送orm

#include<bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int total,n,m,get_num;
    cin>>total;
    while(total--){
        cin>>n>>m;
        int ans=0;
        for(int i=1;i<=n;i++){
            cin>>get_num;
            ans+=get_num;
        }
        if(n==2 || m<n){
            cout<<-1<<endl;
        }else{
            ans*=2;
            cout<<ans<<endl;
            for(int i=1;i<=n;i++){
                int j=(i+1>n?1:i+1);
                cout<<i<<" "<<j<<endl;
            }
        }
    }
    return 0;
}

C. League of Leesinsxml

题意:有一串序列,好比[1,4,2,3,5],给出它每三个数字的排序{[1,4,2],[4,2,3],[2,3,5]},如今将其打乱,大分组顺序和小份内组顺序均可能会变化如变为:blog

{[2,4,3],[1,2,4],[5,3,2]},如今给出被打乱后的序列,请输出它对应的任意一组可能的顺序序列

思路:开始和结尾的数只会出现一次,找到开始和结尾,而后能够肯定开始的那一组,以后每两个数都能肯定第三个数,用map作一下便可。

(我是unordered_map套了vector,初始化每组数中每两个数作一次key,第三个数做为值塞入对应key的vector中,后面判断总的大数组中相邻的数对应key的vector的size为2,间隔数对应key的vector的size为1)

#include<bits/stdc++.h>
using namespace std;
int book[100005];
vector<int>ans;
unordered_map<long long,vector<int> >tree;
vector<int>null_vec;
struct node{
    int a,b,c;
}que[100005];
void solve(int a,int b,int c){
    long long xiao=1LL*min(a,b);
    long long da=1LL*max(a,b);
    long long key=xiao*1000000+da;
    if(tree.find(key)==tree.end()){
        tree[key]=null_vec;
        tree[key].push_back(c);
    }else{
        tree[key].push_back(c);
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int n,a,b,c;
    cin>>n;
    memset(book,0,sizeof(book));
    for(int i=1;i<=n-2;i++){
        cin>>a>>b>>c;
        que[i].a=a;que[i].b=b;que[i].c=c;
        solve(a,b,c);
        solve(a,c,b);
        solve(b,c,a);
        book[a]++;
        book[b]++;
        book[c]++;
    }
    int start,k1,k2,end_p,gg;
    for(int i=1;i<=n;i++){
        if(book[i]==1){
            start=i;
            gg=i+1;
            break;
        }
    }
    for(int i=gg;i<=n;i++){
        if(book[i]==1){
            end_p=i;
            break;
        }
    }
    for(int i=1;i<=n;i++){
        if(que[i].a==start){
            k1=min(que[i].b,que[i].c);
            k2=max(que[i].b,que[i].c);
            break;
        }else if(que[i].b==start){
            k1=min(que[i].a,que[i].c);
            k2=max(que[i].a,que[i].c);
            break;
        }else if(que[i].c==start){
            k1=min(que[i].a,que[i].b);
            k2=max(que[i].a,que[i].b);
            break;
        }
    }
    ans.push_back(start);
    while(ans.size()+3<n){
        long long key=1LL*k1*1000000+1LL*k2;
        int num1=tree[key][0];
        int num2=tree[key][1];
        int type=0;
        int kk1,kk2;
        if(num1==start){
            kk1=min(k2,num2);
            kk2=max(k2,num2);
            type=1;
        }else if(num2==start){
            kk1=min(k2,num1);
            kk2=max(k2,num1);
            type=2;
        }
        long long nk=1LL*kk1*1000000+1LL*kk2;
        if(tree[nk].size()==1){
            swap(k1,k2);
            if(type==1){
                kk1=min(k2,num2);
                kk2=max(k2,num2);
            }else if(type==2){
                kk1=min(k2,num1);
                kk2=max(k2,num1);
            }
        }
        ans.push_back(k1);
        start=k1;k1=kk1;k2=kk2;
    }
    long long gk1=min(start,k1);
    long long gk2=max(start,k1);
    long long ggkey=gk1*1000000+gk2;
    if(tree[ggkey].size()==1){
        swap(k1,k2);
    }
    for(int i=0;i<ans.size();i++){
        cout<<ans[i]<<" ";
    }
    cout<<k1<<" "<<k2<<" "<<end_p<<endl;
    return 0;
}

D. Feeding Chicken

题意:r×c大小的农场养k只鸡,有些单位格上有米粒,如今给鸡分配空间,要求:每一个鸡至少获得一个单位格,每只鸡的活动区域要4联通,本身的区域不能分开,得到米粒最多的鸡和得到米粒最少的鸡的米粒差尽量小。

思路:S型给鸡分配场地便可,扫描得总米粒数为x,有x%k只鸡吃x/k+1粒米,有k-x%k只鸡吃x/k粒米,(我不知道整除时怎么放入总状况因此单独写了一遍整除时的,因此代码比较长(裂开))。

#include<bits/stdc++.h>
using namespace std;
char ditu[105][105];
char ans[105][105];
int t,r,c,k;
int every_l,every_h,cont_h,cont_l;
string biao="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

void solve0(){
    int ct_h=0,ct_l=0;
    for(int i=0;i<r;i++){
        if(i%2==0){
            for(int j=0;j<c;j++){
                if(ditu[i][j]=='R'){
                    ans[i][j]=biao[ct_h];
                    ct_h++;
                }else{
                    if(ct_l<cont_l){
                        ans[i][j]=biao[cont_h+ct_l];
                        ct_l++;
                    }else{
                        if(i==0){
                            ans[i][j]=ans[i][j-1];
                        }else
                            ans[i][j]=ans[i-1][j];
                    }
                }
            }
        }else{
            for(int j=c-1;j>=0;j--){
                if(ditu[i][j]=='R'){
                    ans[i][j]=biao[ct_h];
                    ct_h++;
                }else{
                    if(ct_l<cont_l){
                        ans[i][j]=biao[cont_h+ct_l];
                        ct_l++;
                    }else{
                        ans[i][j]=ans[i-1][j];
                    }
                }
            }
        }

    }
    return;
}

void solve(){
    int ct_h=0,ct_l=0,cont_mi=0;
    for(int i=0;i<r;i++){
        if(i%2==0){
            for(int j=0;j<c;j++){
                if(ditu[i][j]=='R'){
                    cont_mi++;
                    if(ct_h==cont_h){//is small
                        if(cont_mi>every_l){
                            cont_mi=1;
                            ct_l++;
                            ans[i][j]=biao[cont_h+ct_l];
                        }else{
                            ans[i][j]=biao[cont_h+ct_l];
                        }
                    }else{//is big
                        if(cont_mi<every_h){
                            ans[i][j]=biao[ct_h];
                        }else{
                            cont_mi=0;
                            ans[i][j]=biao[ct_h];
                            ct_h++;
                        }
                    }
                }else{
                    if(ct_h==cont_h){
                        if(cont_l==0) ans[i][j]=biao[cont_h-1];
                        else ans[i][j]=biao[cont_h+ct_l];
                    }else{
                        ans[i][j]=biao[ct_h];
                    }
                }
            }
        }else{
            for(int j=c-1;j>=0;j--){
                if(ditu[i][j]=='R'){
                    cont_mi++;
                    if(ct_h==cont_h){//is small
                        if(cont_mi>every_l){
                            cont_mi=1;
                            ct_l++;
                            ans[i][j]=biao[cont_h+ct_l];
                        }else{
                            ans[i][j]=biao[cont_h+ct_l];
                        }
                    }else{//is big
                        if(cont_mi<every_h){
                            ans[i][j]=biao[ct_h];
                        }else{
                            cont_mi=0;
                            ans[i][j]=biao[ct_h];
                            ct_h++;
                        }
                    }
                }else{
                    if(ct_h==cont_h){
                        if(cont_l==0) ans[i][j]=biao[cont_h-1];
                        else ans[i][j]=biao[cont_h+ct_l];
                    }else{
                        ans[i][j]=biao[ct_h];
                    }
                }
            }
        }
    }
    return;
}

int main()
{
    scanf("%d",&t);
    while(t--){
        int rice=0;
        scanf("%d %d %d\n",&r,&c,&k);
        for(int i=0;i<r;i++){
            scanf("%s",ditu[i]);
            for(int j=0;j<c;j++){
                if(ditu[i][j]=='R') rice++;
            }
        }
        every_l=rice/k,every_h=every_l+1,cont_h=rice%k,cont_l=k-cont_h;
        if(every_l==0) solve0();
        else solve();
        for(int i=0;i<r;i++){
            for(int j=0;j<c;j++){
                printf("%c",ans[i][j]);
            }
            printf("\n");
        }
    }
    return 0;
}

E1. Send Boxes to Alice (Easy Version)

题意:一行有n个盒子,每一个盒子有1个或没有巧克力,每次操做能够将第i个盒子中的一个巧克力放入第i-1或者第i+1个盒子中(盒子存在),问最少操做几回,最后全部有巧克力的盒子中的巧克力数能被k整除

思路:先分解质因数,由于是easy版本因此对于每一个质因子pr,每pr个有巧克力的盒子分为一组,枚举放入每个盒子的操做数取和的最小值便可,优化一下前缀后缀暴力就能过。

#include<bits/stdc++.h>
using namespace std;
vector<int>que;

long long solve(int pr)
{
    long long sum=0;//will return the value;
    for(int st=0;st<que.size();st+=pr){
        long long ans=0;
        for(int i=1;i<pr;i++){
            ans+=que[st+i]-que[st];
        }
        long long l=0,r=pr-1,zuo=0,you=ans;
        for(int i=1;i<pr;i++){
            l+=1;
            zuo+=l*(que[st+i]-que[st+i-1]);
            you-=r*(que[st+i]-que[st+i-1]);
            r--;
            ans=min(ans,zuo+you);
        }
        sum+=ans;
    }
    return sum;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int n,get_num;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>get_num;
        if(get_num>0){
            que.push_back(i);
        }
    }
    if(que.size()<=1){
        cout<<-1<<endl;
    }else{
        long long ans=10000000000000000;

        vector<int>prime;
        int size_p=que.size();
        prime.push_back(size_p);
        for(int pr=2;pr*pr<=size_p;pr++){
            bool flag=false;
            while(size_p%pr==0){
                flag=true;
                size_p/=pr;
            }
            if(flag)prime.push_back(pr);
        }
        if(size_p>1)prime.push_back(size_p);

        for(int i=0;i<prime.size();i++){
            ans=min(ans,solve(prime[i]));
        }
        cout<<ans<<endl;
    }
    return 0;
}

 

E2. Send Boxes to Alice (Hard Version)

题意:如E1,只是每一个盒子中巧克力个数Ai范围改成[0,1e6]

思路:仍是先分解质因数,对于一个数Ai,假设当前的质因数为pr,这个位置要知足能被k整除,有两个可能,要么是它日后面搬运pr%k石子,要么是后面往它搬运k−pr%k个石子。

对于每个Ai知足后,由于只会对下一个位置产生影响,因此下一个位置Ai+1算上Ai产生的影响,以后又是一个新的子问题。

最后的答案为:对于每个质因数pr,求每位置i求min(pre[i],pr−pre[i])的和,最后全部和中的最小值及为答案。

#include<bits/stdc++.h>
using namespace std;
int num[1000005];

long long solve(long long pr,int n){
    long long pre=0,ans=0;
    for(int i=1;i<=n;i++){
        pre=(pre+num[i])%pr;
        ans+=min(pre,pr-pre);
    }
    return ans;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int n;
    long long sum=0,ans=1e18;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>num[i];
        sum+=num[i];
    }
    if(sum<=1){
        cout<<-1<<endl;
        return 0;
    }
    for(long long pr=2;pr*pr<=sum;pr++){
        bool flag=false;
        while(sum%pr==0){
            flag=true;
            sum/=pr;
        }
        if(flag) ans=min(solve(pr,n),ans);
    }
    if(sum>1) ans=min(solve(sum,n),ans);
    cout<<ans<<endl;
    return 0;
}

F. Point Ordering

不会搞,23333

相关文章
相关标签/搜索