Codeforces Round #451 Div. 2 C D E
阿新 • • 發佈:2017-12-24
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; returntemp; } 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