Codeforces Round #FF(255) DIV2

OpenSoucre發表於2014-07-14

A - DZY Loves Hash

水題,開闢一個陣列即可

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

int main(){
    int p,n;
    cin >> p >> n;
    vector<bool> buckets(302,false);
    bool flag = false;
    vector<int > x(n);
    for(int i  =0  ; i < n ; ++i) cin >> x[i];
    int i = 0;
    for(i = 0 ; i < n; ++i){
        if(!buckets[x[i]%p]) buckets[x[i]%p] = true;
        else{ cout<<i+1<<endl; break;}
    }
    if(i >= n) cout<<-1<<endl;
}
開闢一個陣列即可

B - DZY Loves Strings

先把給定的字元的值求出來,然後插入權重最大的值即可

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
using namespace std;

int main(){
    string s;
    int k;
    vector<int> w(26,0);
    cin >>s >> k;
    for(int i = 0 ; i < 26; ++ i) cin >>w[i];
    long long res = 0;
    for(int i = 0 ;i < s.length(); ++ i){
        res+=w[s[i]-'a']*(i+1);
    }
    sort(w.begin(),w.end());
    for(int i =s.length(); i < s.length()+k; ++ i){
        res+=w[25]*(i+1);
    }
    cout<<res<<endl;
}
View Code

C - DZY Loves Sequences

題目的意思是給定一個序列,然後找出一個子序列,改變子序列的一個值,使該子序列嚴格單調遞增,求出滿足上述要求最長子序列的長度。

注意一定要是單調遞增

思路是將陣列分塊,每一塊都是嚴格單調遞增的

如 7 2 3 1 5 6

分組後為 [7], [2,3], [1,5,6],影響長度的是組與組之間的間隔

現在記錄下每一個組的開始索引和結束索引,以及長度,所求最大子序列長度有三種可能

(1)如果該陣列只有一個分組,則該長度就是所求結果的長度

(2)max(每個分組的長度+1),即就是每個分組的長度+改變與其相鄰元素的值的最大值

(3)兩個分組合並後的值即max(分組 i + 分組 i+1 )的值,注意這裡分組有兩種情況種情況

    假設分組後兩組元素為[astart1 .... aend1], [astart2 ..... aend2],注意這兩組元素是相鄰的即 start2 == end1+1

    要滿足嚴格單調遞增的情況必須滿足 astart2+1-aend1 > 1 或者 astart2 - aend1-1 >1, 要像下面的用例一樣[1,2,5],[4,5,7]即可

    如果下面的用例

      a、[1,2,4],[3,6,7]這兩個分組無法合併 ,因為astart2 -aend1-1 <=1

      b、[1,2,5],[3,5,7]這兩個分組無法合併, 因為astart2+1-aend1 <=1

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

struct Node{
    int startIdx;
    int endIdx;
    Node(int a = 0,int b = 0): startIdx(a),endIdx(b){};
    int getLength(){return endIdx-startIdx+1;}
};

int main(){
    int n;
    cin >>n;
    vector<int> a(n+1,0);
    vector<Node> aux;
    for(int i = 1;i <=n ; ++i) cin >> a[i];
    int startIdx = 1, maxLength = 0;
    bool flag = false;
    for(int i = 1; i < n ; ++i){
        if(a[i] < a[i+1]){
            if(!flag) {startIdx = i;flag = true;}
        }else{
            aux.push_back(Node(startIdx,i));
            maxLength = max(maxLength,i-startIdx+1);
            startIdx = i+1;
            flag = false;
        }
    }
    if(startIdx == n ) {aux.push_back(Node(n,n));maxLength = max(maxLength,1);}
    else {aux.push_back(Node(startIdx,n));maxLength=max(maxLength,n-startIdx+1);}
    for(int i = 0; i < aux.size()-1; ++ i){
        if(aux[i+1].startIdx+1<=aux[i+1].endIdx && a[aux[i+1].startIdx+1]-a[aux[i].endIdx] > 1) maxLength =max(maxLength,aux[i+1].getLength()+aux[i].getLength());
        if(aux[i].endIdx-1>=aux[i].startIdx && a[aux[i+1].startIdx]-a[aux[i].endIdx-1] > 1 ) maxLength =max(maxLength,aux[i+1].getLength()+aux[i].getLength());
        maxLength =max(maxLength,aux[i].getLength()+1);
    }
    if(aux.size() > 1)  maxLength =max(maxLength,aux[aux.size()-1].getLength()+1);
    cout<<maxLength<<endl;
}
View Code

D - DZY Loves Modification

題目的意思是有一個nxm的矩陣,通過k次操作修改這個矩陣,每次操作包含下面任何一個:

  • 挑選某行,然後累加該行獲得pleasure值,然後該行的每個元素都減去p
  • 挑選某列,然後累加該列獲得pleasure值,然後該列的每個元素都減去p

通過k次操作後,求所有操作pleasure值最大是多少?注意k的範圍是10^6,不能通過暴力解決

解題思路:

  這種題目可以通過手動模擬小資料,瞭解其過程。每次選取的行或列都應該根據貪心從大到小選取,選擇行和選擇列順序是無關的

  設選取了 i 行,則選取了k-i 列,

  假設先選取了i行,然後選取列,則選取列的時候跟選取行相交的元素多減去了p,故選取列的時候在原有列的基礎上少了i*p(該列與i行肯定相交),由於列與列選取互不相影響

  選取k-i列比初始列的值少了i*p*(k-i)

      故只需要在初始矩陣上求出選取i行,選取k-i行的pleasure值,然後減去i*p*(k-i)即可,最後取個最大值

  需要注意的地方是:每行可以操作多次

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <queue>
#include <functional>
#include <utility>
#define LL long long
using namespace std;

struct Node{
    int index;
    LL sum;
    Node(int idx = 0, LL su = 0):index(idx), sum(su){}
    bool operator < (const Node& a)const{
        return sum < a.sum;
    }
};

int main(){
    LL n,m,k,p;
    cin >>n >> m >> k >>p;
    vector<vector<int> > a(n,vector<int>(m,0));
    for(int i = 0 ; i <n ; ++ i){
        for(int j = 0 ; j < m ; ++ j){
            cin >> a[i][j];
        }
    }

    vector<Node> rowSum(n),colSum(m);
    for(int i = 0 ;  i < n; ++ i ){
        LL sum = 0;
        for(int j = 0 ; j < m ; ++ j) sum+=a[i][j];
        rowSum[i]=Node(i,sum);
    }
    for(int j = 0; j < m; ++ j){
        LL sum = 0;
        for(int i = 0 ; i < n ; ++ i) sum+=a[i][j];
        colSum[j]=Node(j,sum);
    }

    priority_queue<Node> que;
    vector<LL> rowRes(k+1,0),colRes(k+1,0);
    for(int i = 0 ; i < n; ++i) que.push(rowSum[i]);
    int cnt = 0;
    LL res = 0;
    while(!que.empty()&& cnt< k){
        Node row =que.top(); que.pop();
        cnt ++;
        res+=row.sum;
        rowRes[cnt] = res;
        row.sum-=m*p;
        que.push(row);
    }
    que=priority_queue<Node>();
    for(int i = 0 ; i < m; ++i) que.push(colSum[i]);
    cnt = 0;res = 0;
    while(!que.empty()&& cnt< k){
        Node col =que.top(); que.pop();
        cnt ++;
        res+=col.sum;
        colRes[cnt] = res;
        col.sum-=n*p;
        que.push(col);
    }
    LL maxRes = -1e18;
    for(int i = 0; i <= k; ++i){
        maxRes = max(maxRes,rowRes[i]+colRes[k-i]-i*(k-i)*p);
    }
    cout<<maxRes<<endl;

}
View Code

 

 

  

相關文章