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

相關文章
相關標籤/搜索