1. 程式人生 > >Codeforces Round #451 Div. 2 C D E

Codeforces Round #451 Div. 2 C D E

eve == ont span har else const 實用 iterator

C。Phone Numbers

之前沒有做過字典樹……感覺這個題字典樹也能做……就拿來練一練字典樹……板子好多地方寫的都不夠好,還需要繼續改……

emmm這個……卡了好久啊……不過好在還是debug出來了……orz

雖然是處理後綴的問題,但是只需要reverse一下就可以變成前綴問題了2333333,然後每一次的字符串都插進去,最後從葉子到根遍歷輸出就可以了……

不過我好像……連葉子到根的遍歷都寫不好嗚嗚嗚……ps:這裏只是為了用trie而用trie……其實用map維護一下直接暴力求解就可以……

//trie樹
 /*1. 字符串檢索
   2.詞頻統計
   3.字符串排序  先序遍歷
   4.前綴匹配
   
*/ #include<bits/stdc++.h> using namespace std; const int MAX=10; string number; int now,cnt=0; int crt[25]; struct trie{ trie *next[MAX]; int v=0; }; trie *root[20]; trie* creat_trie() { trie *temp=(trie*)malloc(sizeof(trie)); for(int i=0;i<10;i++) temp->next[i]=NULL; return
temp; } void insert_trie(trie *r,string s,int k) { trie *p=r; for(int i=0;i<s.length();i++) { int id=s[i]-0; if(p->next[id]==NULL) p->next[id]=creat_trie(); p=p->next[id]; } } void search_trie(trie *r,int k) { int c=0; for(int i=0
;i<10;i++) { if(r->next[i]!=NULL) { c++; search_trie(r->next[i],k); } } if(c==0&&r->v!=-1) { crt[k]++; r->v=-1; } } void print(trie *r) { if(r->v==-1) { reverse(number.begin(),number.end()); cout<<number<<" "; reverse(number.begin(),number.end()); return ; } for(int i=0;i<10;i++) { if(r==root[now]) number=""; if(r->next[i]!=NULL) { number+=char(i+0); print(r->next[i]); number=number.substr(0,number.length()-1); } } } int main() { int n,m; map<string,int>e; string a,b; cin>>n; memset(crt,0,sizeof(crt)); for(int i=0;i<=n;i++) root[i]=creat_trie(); while(n--) { cin>>a; if(e[a]==0) e[a]=++cnt; cin>>m; now=e[a]; while(m--) { cin>>b; reverse(b.begin(),b.end()); insert_trie(root[now],b,now); } } cout<<e.size()<<endl; map<string,int>::iterator it; for(it=e.begin();it!=e.end();it++) { cout<<it->first<<" "; now=it->second; search_trie(root[now],now); cout<<crt[now]<<" "; print(root[now]); cout<<endl; } return 0; }

(好像還有個後綴樹啥的……emmmm還沒有學習……碼著先)

D。Alarm Clock

是個前綴和+貪心的問題麽……看大佬簡潔的代碼是那麽處理的,自己搞得太復雜了……還……好多bug

需要好好想想哪些用前綴和處理更簡潔,比如像這種多長時間內的,多大長度內的問題,可以考慮用前綴和?

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m,k,b;
ll a[1000005];
int main()
{
    cin>>n>>m>>k;
    memset(a,0,sizeof(a));
    for(int i=0;i<n;i++)
    {
      cin>>b;
      a[b]=1;     
    }
    int ans=0;
    for(int i=1;i<=m;i++)
    {
        a[i]+=a[i-1];
        if(a[i]>=k)
        {
            ans+=(a[i]-(k-1));
            a[i]=k-1;
        }
    }
    for(int i=m+1;i<1e6+5;i++)
    {
        a[i]+=a[i-1];
        b=a[i]-a[i-m];
        if(b>=k)
        {
            ans+=(b-k+1);
            a[i]=a[i-m]+k-1;
        }
    }
    cout<<ans<<endl;
    return 0;
}

E。Squares and not squares

想著暴力dfs我也是傻了……orz

依舊還是貪心,這次題……好多貪心……

2種情況……為平方數的個數m<=n/2,ans=(n/2-m)個非平方數變成平方數和的最小值

m>=n/2,ans=(m-n/2)個平方數變為非平方數和的最小值(非0值每個數只需要+1,0需要+2)//註意0需要特判,良心樣例有沒有啊!

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,a[200005],ans;
ll b[200005];
int main()
{
    cin>>n;
    int cnt=0,cnt0=0,cnt1=0;
    for(int i=0;i<n;i++)
    {
     cin>>a[i]; 
     ll c=sqrt(a[i]);
     ll minn=min(a[i]-pow(c,2),pow(c+1,2)-a[i]);
     b[i]=minn;
     if(b[i]==0)
      cnt++;
    if(a[i]==0) cnt0++;
    }
    if(cnt>=n/2&&cnt0<=n/2) ans=cnt-n/2;
    else if(cnt0>n/2)
        ans=cnt-cnt0+2*(cnt0-n/2);
    else 
    {
        ans=0;
           sort(b,b+n);
        for(int i=0;i<n/2;i++)
           ans+=b[i]; 
    }
    cout<<ans<<endl;
    return 0;
}

Codeforces Round #451 Div. 2 C D E