題解Educational Codeforces Round 75 [Rated for Div. 2] (CF1251)


今天開題一個半小時,只做了半小時寫完了前三題。。T3還是最后1min交上去的。。不得不說我們小區維修導致我Rating狂降啊。。。或者說我太菜了(

有看不懂的看看代碼,也許有注釋,如果沒有注釋可以研究一下代碼(應該比較好懂),還看不懂就在底下留言或者私信我,我看到就會給予回復。

A:看看某個字母有沒有連續一段為奇數的,有說明可行。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define it register int
 4 #define il inline
 5 using namespace std;  6 const int N=100005;  7 int T,cn[N],n;  8 char s[N];  9 int main(){ 10     scanf("%d\n",&T); 11     while(T--){ 12         scanf("%s",s+1),n=strlen(s+1); 13         for(it i=0;i<26;++i) cn[i]=0; 14         for(it i=1,j,x;i<=n;i=j){ 15             j=i,x=0; 16             for(;s[j]==s[i]&&j<=n;++j) ++x; 17             if(x&1) cn[s[i]-'a']=1; 18  } 19         for(it i=0;i<26;++i) if(cn[i]) putchar(i+'a'); 20         putchar('\n'); 21  } 22     return 0; 23 }
View Code

B:我們發現0和1可以隨便擺放,於是DP,設f[i][j]表示前i個分配了j個1,可以獲得的最大回文串。

若k是奇數,且len[i]為奇數,可行;若k是偶數,無論len[i]為奇數偶數都可行。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define it register int
 4 #define il inline
 5 using namespace std;  6 const int N=55;  7 int T,n,a[N],o1,o2,f[N][N*N];  8 char s[N][N];  9 il int Max(it p,it q){ 10     return p>q?p:q; 11 } 12 il void ckMax(int &p,it q){ 13     p=(p>q?p:q); 14 } 15 int main(){ 16     scanf("%d\n",&T); 17     while(T--){ 18         scanf("%d\n",&n),o1=0; 19         for(it i=1;i<=n;++i) 20             scanf("%s",s[i]+1),a[i]=strlen(s[i]+1); 21         for(it i=1;i<=n;++i) 22             for(it j=1;j<=a[i];++j) o1+=(s[i][j]=='1'),o2+=(s[i][j]=='0'); 23     // f[i][j]:前i個分配了j個1
24         memset(f,-1,sizeof(f));f[0][0]=0; 25         for(it i=1;i<=n;++i) 26             for(it j=0;j<=o1;++j) 27                 for(it k=0;k<=a[i]&&k+j<=o1;++k) 28                     if(~f[i-1][j]) ckMax(f[i][j+k],f[i-1][j]+((k&1)&&(a[i]&1))+(!(k&1))); 29         printf("%d\n",f[n][o1]); 30  } 31     return 0; 32 }
View Code

C:顯然奇數偶數的相對順序不改變,把奇數偶數搞個數組記錄下,然后歸並排序。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define it register int
 4 #define il inline
 5 using namespace std;  6 const int N=1000005;  7 int T,a[N],pos[N],n,b[N],cna,cnb;  8 char s[N];  9 il void fr(int &num){ 10     num=0;char c=getchar();int p=1; 11     while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar(); 12     while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar(); 13     num*=p; 14 } 15 int main(){ 16  fr(T); 17     while(T--){ 18         scanf("%s",s+1); 19         n=strlen(s+1);cna=cnb=0; 20         for(it i=1,x;i<=n;++i) ((x=s[i]-'0')&1)?a[++cna]=x:b[++cnb]=x; 21         it i=1,j=1; 22         while(i<=cna&&j<=cnb) 23             if(a[i]<b[j]) printf("%d",a[i]),++i; 24             else printf("%d",b[j]),++j; 25         while(i<=cna) printf("%d",a[i]),++i; 26         while(j<=cnb) printf("%d",b[j]),++j; 27         putchar('\n'); 28  } 29     return 0; 30 } 31 //所有的奇數和偶數相對位置不變 把奇數偶數搞個數組記錄下
View Code

剩下三題是考后補的:

D:一眼二分。。早知道先開D了(分多啊)二分一下最小的可行答案並且進行檢驗。一個小貪心,最開始按照l,r從大到小排序。很涼心地放D題。。

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #define it register int
 4 #define il inline 
 5 using namespace std;
 6 const int N=1000005;
 7 typedef long long ll;
 8 struct ky{
 9     ll a,b;
10     bool operator<(const ky&p)const{
11         return a^p.a?a>p.a:b>p.b;
12     }
13 }a[N];
14 int T,n,half;
15 ll m;
16 il bool ck(ll x){
17     ll cnt=0,tot=0;
18     for(it i=1;i<=n;++i) a[i].a>=x?tot+=a[i].a,++cnt:(a[i].b<x?tot+=a[i].a:(cnt<half?++cnt,tot+=x:tot+=a[i].a));
19     if(cnt<half) return 0;
20     return tot<=m;
21 }
22 il void ms(){
23     ll l=0,r=1e18,mid;
24     while(l<=r) mid=l+r>>1,ck(mid)?l=mid+1:r=mid-1;
25     printf("%I64d\n",r);
26 }
27 namespace io {
28     const int SIZE = (1 << 21) + 1;
29     char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55];
30     int f, qr;
31 #define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
32     inline void flush () {fwrite (obuf, 1, oS - obuf, stdout);oS = obuf;}
33     template <class I>
34     inline void fr (I &x) {
35         for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1;
36         for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15);
37         x *= f;
38     }
39     struct Flusher_ {~Flusher_() {flush();}} io_flusher_;
40 }
41 using io :: fr;  
42 int main(){ 
43     fr(T);
44     while(T--){
45         fr(n),fr(m),half=(n+1>>1);
46         for(it i=1;i<=n;++i) fr(a[i].a),fr(a[i].b);
47         sort(a+1,a+1+n),ms();
48     }
49     return 0;    
50 }
View Code

E:看到雙倍經驗直接看hard version 。。然后以為是個dp。。突然發現可以貪心。。然后就隨手一發貪心。。過了之后看到標簽還有binary search ,我並沒有想到,如果有會二分做法的大佬請留言教我一下或私信D我,謝謝指教!

更好玩的是交了easy version 之后看到tag是dp和greedy,並沒有binary search,難道說hard version的算法不適用於easy version?幸好我打了貪心兩邊都能過

 1 #include<stdio.h>
 2 #include<vector>
 3 #include<queue>
 4 #include<algorithm>
 5 #define it register int
 6 #define il inline 
 7 using namespace std;
 8 const int N=1000005;
 9 int T,n; 
10 vector<int> g[N];
11 long long ans;
12 il void fr(int &num){
13     num=0;char c=getchar();int p=1;
14     while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar();
15     while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar();
16     num*=p;
17 }
18 priority_queue<int,vector<int>,greater<int> > q;
19 int main(){ 
20     fr(T);
21     while(T--){
22         fr(n),ans=0;
23         for(it i=1,x,y;i<=n;++i) fr(x),fr(y),g[x].push_back(y);//收買i要x人或者花y元
24         for(it i=n-1;i>=0;--i){//注意到一個顯而易見的事實就是人數不會超過n
25             for(it j=0,sz=g[i].size();j<sz;++j) q.push(g[i][j]);
26             while(q.size()>n-i) ans+=q.top(),q.pop();//選前n-i小的人進行收買
27         }
28         printf("%I64d\n",ans);
29         for(it i=0;i<n;++i) g[i].clear();while(!q.empty()) q.pop();//多測不清空 爆零兩行淚
30     }
31     return 0;
32 }
View Code

F:太遲了先咕着明早更。

 

至少前五題趕在官方題解出來之前寫完了自己的題解。。我還是太菜了,還要繼續磨礪吖!

有更好的做法歡迎留言哦~

upd:請教了機房大佬發現F我不會。。那么就看似咕咕實則不會吧!(棄F坑)

upd:機房大佬告訴我B有更好的O(n)做法:亂搞。(吊錘我的dp做法,還好我的程序時間復雜度比較穩……)

首先可以證明要么有n個回文串要么有n-1個回文串,因為我們可以通過舍棄最多一個串使得剩下的都成立。

然后就可以進行亂搞。我們可以記錄一下有多少個奇數串,多少個偶數串。(這里的奇數偶數指的是長度)。如果有>1的奇數串答案肯定為n,如果只有一個奇數串答案肯定是n-1,如果全是偶數串,判斷一下0和1的個數,如果都是奇數個答案就是n-1,否則答案為n。代碼就不貼了(我也懶得寫)。

upd:機房大佬告訴我B題我的程序理論時間復雜度是O(n^5)。。但是極限數據只需要0.8s,肯定是跑不滿的。。如果有知道我B題dp的實際時間復雜度的大佬請私信我或者在底下留言,謝謝!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM