Codeforces Round #455 (Div. 2)-A,B,C,D,E

http://codeforces.com/contest/909
差F題了,有機會再補吧。F是思維題。
斷斷續續補了好久。。
比賽就做了A,B 。
A
給你兩個名字,要求一個名字由這兩個的前綴拼接順序而成並且字典序最小。
把問題轉化一下,想要長度最小,最後一個名字只取首字母。
然後在第一個名字內找比 二名字首字母小的字母

#include <bits/stdc++.h>
using namespace std;
int main()
{  string a,b;
   cin>>a>>b;
   string w;
   w+=a[0];
   for(int i=1;i<a.length();i++){
      if(a[i]<b[0])
        w+=a[i];
        else break;
   }
   w+=b[0];
   cout<<w<<endl;
    return 0;
}

B給定一個長度n,求1-n之間長度小於等於n的所有線段,可以累加成多少線段。
數據範圍100,一看圖就知道啥意思,暴力

#include <bits/stdc++.h>
using namespace std;
int sum[200];
int main()
{    int m;
      scanf("%d",&m);
      for(int i=1;i<=m;i++){
          for(int j=i;j<=m;j++){
              for(int k=i;k<=j;k++)
                 sum[k]++;
          }
      }
      int max1=-1;
      for(int i=1;i<=m;i++)
         max1=max(sum[i],max1);
         cout<<max1<<endl;





    return 0;
}

c python大法好。
給定兩個字母。s爲正常語句,f爲循環語句。問有多少縮進形式。
最開始的思路是 統計f字串長度,然後快速冪qwq
有點迷,我現在都忘記爲啥這樣寫了 。。
正解:dp,當f時,狀態轉移方程爲
dp[i][j]=dp[i-1][j-1];//有i行,第i行 縮進爲j時的狀態。
有f就縮進加1。嚴格縮進。
當爲s時。
大縮進 可以往小縮進移動(縮進越大,距離左端越大。)
求一遍後綴和。

    #include <bits/stdc++.h>
using namespace std;
/* 動態規劃問題。
   考慮一點,那就是我們最後的結束,肯定是語句爲界
   對於有F語句的,是之前上一行的各個 縮進矩陣取一下就行
   對於S語句,我們就求和就行。

*/
const int maxn=5006;
int dp[maxn][maxn];
typedef long long ll;
const ll mod=1e9+7;
int m;
char ch;
int main()
{   scanf("%d",&m);
    getchar();
    dp[0][0]=1;
    for(int i=1;i<=m;i++){
        //scanf(" %c",&ch);
        ch=getchar();
        if(ch=='f'){
            for(int j=0;j<=i-1;j++){
              dp[i][j+1]=dp[i-1][j];
            }
        }
        else{
           ll sum=0;
           for(int j=m;j>=0;j--){
              sum=(sum+dp[i-1][j])%mod;
              dp[i][j]=sum;
           }
        }
        getchar();
    }
    //cin>>ch;
    /*for(int i=0;i<=m;i++){
       for(int j=0;j<=m;j++){
           printf("%d ",dp[i][j]);
       }
       cout<<endl;
    }
    /*for(int i=m;i>=0;i--){
      if(dp[m][i]!=0){
         printf("%lld\n",dp[m][i]);
         break;
      }
    }*/
    printf("%d\n",dp[m][0]);
    return 0;
}

D:給定一個字符串,如果第i的位置和 他相鄰的不想等,就把他們刪掉,有一個不想等刪倆,兩個相鄰的都不想等就刪除3。
思路:如果暴力實在是有點。。 放D題幹嘛。
並且我發現 list並沒有刪除 節點的O(1)的函數。暗道自己寫一個循環鏈表? 最後沒有寫,感覺不應該是這樣。
維護一個vector。表示每段。然後暴力。

 #include <bits/stdc++.h>
using namespace std;
/* 加油啊。 爲未來
  暴力的寫法,
    我自己不I昂I想你
*/
vector<pair<char,int> >v;
vector<pair<char,int> >s;
string ss;
int main(){
     cin>>ss;
    long long ans=0;
      v.push_back(make_pair(ss[0],1));
     for(int i=1;i<ss.length();i++){
         //if(v.size()==0)
           //v.push_back(make_pair(ss[i],1));
          if(ss[i]==v[v.size()-1].first)
         {  v[v.size()-1].second++;
         }
         else
            v.push_back(make_pair(ss[i],1));
     }
     /*for(int i=0;i<v.size();i++){
       cout<<v[i].first<<" "<<v[i].second<<"::";
     }*/
     //cout<<endl;
      s.clear();
      while(v.size()>1){
           s.clear();
           for(int i=0;i<v.size();i++){
              if(i==0||i==(v.size()-1))
                 v[i].second-=1;
              else
                 v[i].second-=2;
           }
           ans++;
           int aa=0;
           while(v[aa].second<=0&&aa<v.size()) aa++;
           //這個循環沒有aa<v.size()是會re的。比方說ababababa這               種情況。,第一次這個循環就不會停。。
           s.push_back(v[aa]);
           for(int i=aa+1;i<v.size();i++){
               if(v[i].second<=0){
                 continue;
               }
               else{
                    //if(s.size()==0) s.push_back(v[i]);
                  if(v[i].first==s[s.size()-1].first){
                   s[s.size()-1].second+=v[i].second;
                 }
                 else
                  s.push_back(v[i]);
               }
           }
           /*for(int i=0;i<s.size();i++){
       cout<<s[i].first<<" "<<s[i].second<<"::";
     }
     cout<<endl;
     */
          v=s;
      }
       printf("%lld\n",ans);
    return 0;
}          

E:給定一個有向 圖(前趨圖?),表示每個任務的依賴關係,a連b表示b依賴a, 當a完成了,b才能完成。
有的處任務只能在主處理器上做有的只能在協處理器,當一個任務所依賴的任務都完成或者都在 一個處理器上,我們就把他們放在一個處理器上,
問最少需要多少協處理器。
一種是類似暴力的方法,記錄每個任務所依賴的事件個數,然後存一個 主處理器隊列和 協處理器隊列,循環bfs。

#include <bits/stdc++.h>

using namespace std;

int main()
{
int n,mm;
cin>>n>>mm;
vector<int>typ(n);
vector<vector<int> >g(n);
for(int i=0;i<n;++i) cin>>typ[i];
vector<int>cnt(n,0);
for(int i=0;i<mm;++i)
{
    int x1,x2;
    cin>>x1>>x2;
    g[x1].push_back(x2);
    cnt[x2]++;
}
queue<int> c,m;
for(int i=0;i<n;++i)
{
    if(cnt[i]==0)
    {
        if(typ[i]==0) m.push(i);
        else c.push(i);
    }
}
//cout<<c.size()<<' '<<m.size()<<'\n';
int ans=0;
while(!c.empty()||!m.empty())
{
    while(!m.empty())
    {
        int x=m.front();
        for(int i=0;i<g[x].size();++i)
        {
            cnt[g[x][i]]--;
            if(cnt[g[x][i]]==0)
            {
                if(typ[g[x][i]]==0) m.push(g[x][i]);
                else c.push(g[x][i]);
            }
        }
        m.pop();
    }
    if(!c.empty()) ++ans;
    while(!c.empty())
    {
        int x=c.front();
        for(int i=0;i<g[x].size();++i)
        {
            cnt[g[x][i]]--;
            if(cnt[g[x][i]]==0)
            {
                if(typ[g[x][i]]==0) m.push(g[x][i]);
                else c.push(g[x][i]);
            }
        }
        c.pop();
    }
}
cout<<ans;
return 0;
}

另一個版本

#include <bits/stdc++.h>
using namespace std;
/* 1可以發現他們的遞歸關係。
    U爲根,v爲所依賴的(U->v有一條邊。)
    那麼 T(U)=max(T(s)+S,T(u));
    當u在協處理器上時而V全在主處理器上時。S爲1
     否則S爲0.
   2 用topsort的方法來寫。
     其實還是那個遞歸關係啦。
   PS:我之前寫過一個 topsort。但是我是把所有的葉子節點給鏈接到一起。
   因爲 我感覺 就算沒有鄰接關係的點也是可能在一個主處理器上。
   而我是使用 u,v是否相等來判斷 協處理器 的數量。。 這樣會多算。
   但是 這樣寫了 破壞了原來的鄰接關係。樣例1就不對。
     分析 6種情況:
     1 U,V均爲協處理器,不增加。(可以放到一個協處理器上)
     2 u爲協,v全爲主,加1
     3 u爲協,V部分爲協,v部分一定在一個協處理器上。
     4 u爲主,v爲協,不加。v在一起
     4 u爲主,v爲主,不加。v在一起
     6 u爲主,v主協均有。 v在一起
   然後維護最大的T就行。
   注意有多個根,用記憶化維護一下。
不記憶化會T。
*/
const int maxn=1e5+200;
int t[maxn];
vector<int>g[maxn];
int typ[maxn];
int du[maxn];
bool vis[maxn];
void dfs(int u,int pre){
     int sum=0;
     //cout<<u<<" "<<g[u].size()<<" "<<t[u]<<endl;
     if(!g[u].size()&&typ[u]==1&&!vis[u])
        {t[u]++;
        //cout<<u<<"zuobiao"<<endl;
        vis[u]=true;
        return;}
        vis[u]=true;
     for(int i=0;i<g[u].size();i++){
         if(g[u][i]==pre) continue;
         int to=g[u][i];
         if(!vis[to])
             dfs(to,u);
         if(typ[to]==0&&typ[u]==1)
       t[u]=max(t[u],t[to]+1);
         else
         t[u]=max(t[u],t[to]);
     }
      //else if(sum<g[u].size()&&typ[u]==1)
        //t[u]=1;
       return;
}
int main()
{    int m,n,a,b;
     scanf("%d%d",&m,&n);
     for(int i=0;i<m;i++){
         scanf("%d",&typ[i]);
     }
     for(int i=0;i<n;i++){
         scanf("%d%d",&a,&b);
         g[a].push_back(b);
         du[b]++;
     }
     int aim=0;
     for(int i=0;i<m;i++){
         if(!du[i]){
         aim=i;
         dfs(i,-1);
         //break;
         }
     }
     int maxx=-1;
     for(int i=0;i<m;i++){
       maxx=max(maxx,t[i]);
       //cout<<t[i]<<" ";
       }
     printf("%d\n",maxx);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章