Codeforces Round #603 (Div. 2)

Codeforces Round #603 (Div. 2)node

A. Sweet Problemios

題意:多組數據,每組數據給出3種顏色的糖果,規定天天吃2顆糖果,顏色不能相同,問最多吃幾天。c++

思路:3種糖果按照個數多少排序獲得a≤b≤c,①若a+b≤c,則天天吃 c 和 a,b中的一種,能夠吃a+b天。②若a+b>c,則先吃a和c讓c和b同樣多,而後若剩餘的a爲偶數則全部糖能夠都吃完,若爲奇數則最後會剩餘1顆,因此此種狀況對應天數爲(a+b+c)/2天。ide

#include<bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    long long n;
    long long num[3];
    cin>>n;
    while(n--){
        cin>>num[0]>>num[1]>>num[2];
        sort(num,num+3);
        if(num[0]+num[1]<=num[2]){
            cout<<num[0]+num[1]<<endl;
        }else{
            cout<<(num[0]+num[1]+num[2])/2<<endl;
        }
    }
    return 0;
}
View Code

B. PIN Codesui

題意:多組數據,每組數據給出n個4位密碼,如今要讓給出的密碼兩兩不相同,且每次只能更改一個密碼的1位,問至少修改多少次並按順序輸出更改後的全部密碼。spa

思路:由於n最大爲10,因此密碼修改能夠只考慮1位,能夠先把全部的pin code都放入一個unordered_map中並統計相應的個數,而後將重複的pin code最後一位進行更改找到沒出現過的便可。code

#include<bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t;
    cin>>t;
    string shuru[20];
    while(t--){
        int n,ans=0;
        unordered_map<string,int>tree;
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>shuru[i];
            if(tree.find(shuru[i])==tree.end()){
                tree[shuru[i]]=1;
            }else{
                tree[shuru[i]]++;
            }
        }
        for(auto i=tree.begin();i!=tree.end();i++){
            ans+=(*i).second-1;
        }
        cout<<ans<<endl;
        for(int i=1;i<=n;i++){
            if(tree[shuru[i]]>1){
                string s=shuru[i];
                for(int j=0;j<=9;j++){
                    s[3]=j+'0';
                    if(tree.find(s)==tree.end()){
                        tree[s]=1;
                        cout<<s<<endl;
                        tree[shuru[i]]--;
                        break;
                    }
                }
            }else{
                cout<<shuru[i]<<endl;
            }
        }
    }
    return 0;
}
View Code

C. Everyone is a Winner!blog

題意:多組數據,每組數據給出一個分值n,定義每一個人的得分爲n除以人數k(向下取整),問一共有多少種不一樣的分數。排序

思路:對於給定的n,i 從1循環到√n,(n/i) 和 (n/(n/i)) 是不一樣的分數,最後把0加上便可。ci

#include<bits/stdc++.h>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t;
    cin>>t;
    while(t--){
        long long n;
        set<long long>tree;
        cin>>n;
        for(long long i=1;i*i<=n;i++){
            long long ans=n/i;
            if(tree.find(ans)==tree.end()){
                tree.insert(ans);
                tree.insert(n/ans);
            }
        }
        tree.insert(0);
        cout<<tree.size()<<endl;
        for(auto i=tree.begin();i!=tree.end();i++){
            cout<<(*i)<<" ";
        }
        cout<<endl;
    }
    return 0;
}
View Code

D. Secret Passwords

題意:有n個密碼,每一個密碼都是由小寫字母則稱,如今給密碼分類,有2個標準。

· 若 密碼a 和 密碼b 都含有某個相同的字母,則a和b同類

· 若 密碼a 和 密碼c 同類,密碼b 和 密碼c 同類,則 密碼a 和 密碼b 同類。

問有幾種不一樣類型的密碼。

思路:並查集,依次將全部含有字母a的密碼視爲一個集團,merge在一塊兒。再將含有字母b的密碼視爲一個集團,merge在一塊兒……以此類推到字母z。最後查詢有幾個不一樣的集團便可。

#include<bits/stdc++.h>
using namespace std;
int father[200005];
vector<vector<int> >vec(27);
 
void init(int n){
    for(int i=1;i<=n;i++){
        father[i]=i;
    }
    return;
}
 
int getfather(int x){
    if(father[x]==x) return x;
    else return father[x]=getfather(father[x]);
}
 
void merge(int x,int y){
    int xx=getfather(x);
    int yy=getfather(y);
    if(xx<yy){
        father[xx]=yy;
    }else{
        father[yy]=xx;
    }
}
 
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int n;
    string s;
    cin>>n;
    init(n);
    for(int i=1;i<=n;i++){
        cin>>s;
        unordered_set<char>tree;
        for(int j=0;j<s.size();j++){
            tree.insert(s[j]);
        }
        for(auto j=tree.begin();j!=tree.end();j++){
            vec[(*j)-'a'].push_back(i);
        }
    }
    for(int i=0;i<26;i++){
        for(int j=1;j<vec[i].size();j++){
            merge(vec[i][j-1],vec[i][j]);
        }
    }
    unordered_set<int>ans;
    for(int i=1;i<=n;i++){
        ans.insert(getfather(father[i]));
    }
    cout<<ans.size()<<endl;
    return 0;
}
View Code

E. Editor

題意:你要對文本進行編輯,你一開始的下標爲起始點(文本範圍是左邊從起始點開始到右邊能夠爲無窮遠),你有n個操做,‘R’和‘L’分別是向右移動1格光標和向左移動一格光標(向左不能越過起始點),其餘字符X爲替換該光標對應位置的文本爲X,每次操做後進行一個查詢,查詢所有文本的括號是否合法,若不合法輸出-1,若合法則輸出所有括號的最大深度。

思路:強制在線操做。對於全部的操做能夠分爲3類,添加括號,刪除括號和無影響。(將起始點座標視爲1)在 i 位置添加一個 「(」 ,則視爲對區間 [ 1 , i ]全部數減一。i 位置添加一個「)」,則視爲對區間[ 1 , i ]全部數加一。刪除括號則相反。每次查詢若左端點若爲0且所有區間[1,n]的最小值大於0,則括號合法,且所有區間[1,n]的最大值爲括號的最大深度。能夠維護一顆線段樹進行區間更新和維護區間最值。

#include <iostream>
#include <cstdio>
#define ll long long
using namespace std;
const ll MAXN = 1e6+10;
struct Tree {
        ll l,r;//節點左右端點
        ll sum;//求和
        ll lazy;//延遲標記
        ll maxn;//最大值
        ll minn;// 最小值
} tree[MAXN<<2];
char zifu[1000005];
void push_up(ll node) { 
    tree[node].sum=tree[node<<1].sum+tree[node<<1|1].sum;
    tree[node].maxn=max(tree[node<<1].maxn,tree[node<<1|1].maxn);
    tree[node].minn=min(tree[node<<1].minn,tree[node<<1|1].minn);
}
void push_down(ll node, ll length) {
    if(tree[node].lazy) { 
        tree[node<<1].lazy+=tree[node].lazy;
        tree[node<<1|1].lazy+=tree[node].lazy;
        tree[node<<1].sum+=(length-(length>>1))*tree[node].lazy;
        tree[node<<1|1].sum+=(length>>1)*tree[node].lazy;
        tree[node<<1].minn+=tree[node].lazy;
        tree[node<<1|1].minn+=tree[node].lazy;
        tree[node<<1].maxn+=tree[node].lazy;
        tree[node<<1|1].maxn+=tree[node].lazy;
        tree[node].lazy = 0;
    }
}
void build(ll l,ll r, ll node) { 
    tree[node].lazy = 0;
    tree[node].l=l;
    tree[node].r=r;
    if(l==r) {
        //cin>>tree[node].sum;
        tree[node].sum=0;
        tree[node].minn=tree[node].sum;
        tree[node].maxn=tree[node].sum;
        return;
    }
    ll mid=(l+r)>>1;
    build(l,mid,node<<1);
    build(mid+1,r,node<<1|1);
    push_up(node);
}
void update(ll left,ll right,ll key, ll node) { 
    if(tree[node].l>=left && tree[node].r<=right) {
        tree[node].sum+=(tree[node].r-tree[node].l+1)*key;
        tree[node].minn+=key;
        tree[node].maxn+=key;
        tree[node].lazy+=key;
        return;
    }
    push_down(node,tree[node].r-tree[node].l+1);
    ll mid=(tree[node].r+tree[node].l)>>1;
    if(left<=mid) update(left,right,key,node<<1);
    if(right>mid) update(left,right,key,node<<1|1);
    push_up(node);
}
ll query(ll left,ll right,ll node) { 
    if(tree[node].l>=left && tree[node].r<=right) {
        return tree[node].sum;
    }
    push_down(node,tree[node].r-tree[node].l+1);
    ll mid=(tree[node].r+tree[node].l)>>1;
    ll ans=0;
    if(left<=mid) ans+=query(left,right,node<<1);
    if(right>mid) ans+=query(left,right,node<<1|1);
    return ans;
}
ll query_min(ll left,ll right,ll node) { 
    if(tree[node].l>=left && tree[node].r<=right) {
        return tree[node].minn;
    }
    push_down(node,tree[node].r-tree[node].l+1);
    ll mid=(tree[node].r+tree[node].l)>>1;
    ll ans=0x7fffffff;
    if(left<=mid) ans=min(ans,query_min(left,right,node<<1));
    if(right>mid) ans=min(ans,query_min(left,right,node<<1|1)) ;
    return ans;
}
ll query_max(ll left,ll right,ll node) { 
    if(tree[node].l>=left && tree[node].r<=right) {
        return tree[node].maxn;
    }
    push_down(node,tree[node].r-tree[node].l+1);
    ll mid=(tree[node].r+tree[node].l)>>1;
    ll ans=-0x7fffffff;
    if(left<=mid) ans=max(ans,query_max(left,right,node<<1));
    if(right>mid) ans=max(ans,query_max(left,right,node<<1|1));
    return ans;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int n,point=1,last_ans=0;
    cin>>n;
    build(1,n,1);
    string s;
    cin>>s;
    for(int i=0;i<s.size();i++){
        if(s[i]=='R'){
            cout<<last_ans<<" ";
            point++;
        }else if(s[i]=='L'){
            cout<<last_ans<<" ";
            point=max(1,point-1);
        }else{
            if(zifu[point]=='('){
                update(1,point,1,1);
            }else if(zifu[point]==')'){
                update(1,point,-1,1);
            }
            if(s[i]=='('){
                update(1,point,-1,1);
            }else if(s[i]==')'){
                update(1,point,1,1);
            }
 
            int minn=query_min(1,n,1);
            int maxx=query_max(1,n,1);
            int left_point=query(1,1,1);
            if(minn<0 || left_point!=0){
                cout<<-1<<" ";
                last_ans=-1;
            }else{
                cout<<maxx<<" ";
                last_ans=maxx;
            }
            zifu[point]=s[i];
        }
    }
    cout<<endl;
    return 0;
}
View Code
相關文章
相關標籤/搜索