東華OJ 陣列競賽 分糖果

Pure_Silly發表於2020-12-11

前言:最近一直先熟悉容器,用容器解題。但是東華OJ某些很好用的新C++標準的功能用不了,再加上自己對容器不熟悉。所以最近應該經常能在註釋裡看見不對的用容器的解法。

題意理解

不進位的二進位制很好理解。就是同位的數若相同就是0,不相同就是1.不進位正好減少了運算。
然後要求求最大的價值這句話就很容易讓人以為是動態規劃了。。(至少我這種蒟蒻第一瞬間的反應就是。。。
但結合第一條資訊很容易發現,如果最後要在不進位的二進位制運算下相同的價值,就是運算後左右兩堆的各位數字相同。如果再把這兩堆合為一堆,那麼很明顯,題意其實是在叫我們判斷是否這給出的所有糖果的價值在不進位的二進位制運算後各位都為0.如果想到這兒這題就很簡單了。

分解

三部分:

  1. 輸入
  2. 進位制轉化
  3. 判斷各位運算後結果是否都為0

解決方法

  1. 輸入準備
    根據前面的分析,如果滿足結果各位為0,那麼最大的價值自然就是所有價值和-最小价值的糖果價值。所以在輸入的同時就可以求所有糖果和

  2. 進位制轉換
    對於一個10進位制的數,轉換成一個n進位制的數。只要先%n得到最高位的數,再/n;反覆進行直到為0.

  3. 判斷各位的數是否為0
    在運算的途中將運算的結果轉存到下一位,反覆進行,最終的運算結果也就轉移到了最後一位。最後判斷運算結果時只需要將最後一位拿出來比較就行了。

#include <bits/stdc++.h>

using namespace std;

int main()
{
    int t;
    cin>>t;
    for(int i=0;i<t;i++){
        //進位制轉換
        //求最優解
        //分成不為空的兩個堆
        //把小弟弟的堆單獨分出來,從最小的開始判斷是否會滿足二進位制不進位相同
        vector<int> candy;
        int k;
        cin>>k;
        int sum=0;//所有糖果價值總和
        for(int j=0;j<k;j++){
            int temp;
            cin>>temp;
            sum+=temp;
            candy.push_back(temp);
        }
        vector<vector<int> > value;
        sort(candy.begin(),candy.end(),less<int>());
        for(int i=0;i<k;i++){//從大到小每個數的二進位制表示
            vector<int> value2(8,0);
            int temp = candy[i];
            int j =0;
            while(temp){
                value2[j]=(temp%2);
                temp/=2;
                j++;
            }
            value.push_back(value2);
        }
        //升序排列的二進位制
        //因為最後結果一定要求相同,若相同則結果一定相加為0
        //所以直接把所有的位相加。若為0則可分。
        int last =0;
        for(int i=0;i<8;i++){
            for(int j=1;j<k;j++){
                if(value[j-1][i]==value[j][i]){
                    value[j][i]=0;
                }
                else{
                    value[j][i]=1;
                }
                last = j;
            }
        }
        bool flag =1;
        for(int i=0;i<8;i++){
            if(value[last][i]!=0){
                flag =0;
                break;
            }
        }
        if(flag){
            cout<<sum-candy[0]<<endl;
        }
        else{
            cout<<"NO"<<endl;
        }
        /*
        for(vector<vector<int> >::iterator itr = value.begin();itr!=value.end();itr++){
            for(int j=0;j<(*itr).size();j++){
                cout<<(*itr)[j]<<" ";
            }
            cout<<endl;
        }
        */
    }
    return 0;
}

相關文章