Educational Codeforces Round 74 (Rated for Div. 2)

  我叼,打的時候CF被ddos了,還有這種操做?害得我只能睡覺html

  最後一題留坑ios

   A. Prime Subtractionc++

   覺得是求GCD,上去wa一發。。。後來發現,y-x=C,若是C不爲1,那麼確定能夠由素數組成,偶數直接+2,奇數就是3+2*k ,k>=0數組

#include<bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
using namespace std;
int main(){
  int t;
  LL a,b;
  scanf("%d",&t);
  while(t--){
    scanf("%lld%lld",&a,&b);
    if (a-b==1){
        printf("NO\n");
    }else {
        printf("YES\n");
    }
  }
  return 0;
}
View Code

  B 先打遠的,每次打完,判斷一下是否有被震到x<0的,直接模擬便可ide

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
const int maxx = 2e5+6;
int a[maxx];
vector<int>v;
bool cmp(int x,int y){
   return x<y;
}
int main(){
   int q;
   int n;
   long long rr;
   scanf("%d",&q);
   while(q--){
      v.clear();
      scanf("%d%lld",&n,&rr);
      for (int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        v.push_back(a[i]);
      }
      sort(v.begin(),v.end(),cmp);
      v.erase(unique(v.begin(),v.end()),v.end());
      int l=0,r=v.size()-1;
      long long step=0;
      int ans=0;
      while(l<=r){
         ans++;
         r--;
         step+=rr;
         while(l<=r && v[l]-step<=0){
             l++;
         }
      }
      printf("%d\n",ans);
   }
   return 0;
}
View Code

  C. Standard Free2playui

   咱們發現只要兩個數間隔差>=2好比5-3,你必定能夠先到4;100-1你必定能夠先到2,而後咱們判斷若是當前和下一個是連續的,也就是說3-2,那麼你能夠先到4,而後3的狀態改變,而後到2,不然就不行,咱們spa

就必須用一個魔法值,前面說了a[i+1]-a[i]>1那麼你能夠直接改變當前i的狀態,而後走到a[i+1]+1的狀態。最後判斷一下,最後的狀態是否是高度大於2,若是是的話,咱們直接改變最後的狀態,而後就能夠到0了。3d

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
using namespace std;
const int maxx = 2e5+6;
int a[maxx];
int main(){
  int t;
  int h,n;
  scanf("%d",&t);
  while(t--){
    scanf("%d%d",&h,&n);
    for (int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int cnt=0;
    for (int i=1;i<=n;i++){
        if (a[i]>=h){
            continue;
        }
        if (h-a[i]>1){
            h=a[i]+1;
        }
        if (i<n){
            if (a[i+1]==a[i]-1){
                h=a[i+1];
            }else{
                cnt++;
                h=a[i];
            }
            continue;
        }
        if (h>2)cnt++;
    }
    printf("%d\n",cnt);
  }
  return 0;
}
View Code

  D  找出全部的串,每個字符都至少屬於一個迴文串,發現其實這種迴文串不少,咱們反着考慮,找不知足的,那麼只有ABBBBB,BAAAAAA,AAAAB,BBBBBA這四種類型,其餘的都是,由於字符畢竟只有兩種,code

那麼先後掃一遍便可,htm

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#define LL long long
using namespace std;
const int maxx= 3e5+6;
char a[maxx];
int main(){
  LL n;
  while(~scanf("%lld",&n)){
    scanf("%s",&a);
    int len=strlen(a);
    LL ans=n*(n-1)/2;
    int pre=0;
    for (int i=1;i<len;i++){
        if (a[i]==a[i-1])continue;
        ans++;
        ans-=(i-pre);
        pre=i;
    }
    pre=len-1;
    for (int i=len-2;i>=0;i--){
        if (a[i]==a[i+1])continue;
        ans-=(pre-i);
        pre=i;
    }
    printf("%lld\n",ans);
  }
  return 0;
}
View Code

  E 頗有意思,咱們暫時也不怎麼懂,這個DP太秀了。。。咱們發現位數只有20位,那麼其實能夠經過枚舉已經安排的狀態來考慮。

  當前狀態i表明當前i的二進制位上的英文單詞是否被安排

  參考一下

http://www.javashuo.com/article/p-tynacpbm-dk.html

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxx = 1e5+6;
const int maxn = 2e6+7;
char str[maxx];
LL dp[maxn];
LL cnt[30][30];
int main(){
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        scanf("%s",str);
        int len=strlen(str);
        for (int i=1;i<len;i++){
             int x=str[i-1]-'a';
             int y=str[i]-'a';
             if (x!=y)cnt[x][y]++,cnt[y][x]++;
        }
        for (int i=1;i<=(1<<m);i++){
            dp[i]=INT_MAX;
        }
        for (int i=0;i<(1<<m)-1;i++){
            LL c=__builtin_popcount(i);
            for (int j=0;j<m;j++){
                if(!(i&(1<<j))){
                    LL tmp=dp[i];
                    for (int k=0;k<m;k++){
                        if (i&(1<<k)){
                            tmp+=cnt[j][k]*c;
                        }else {
                            tmp-=cnt[j][k]*c;
                        }
                    }
                    dp[i|(1<<j)]=min(dp[i|(1<<j)],tmp);
                }
            }
        }
        printf("%lld\n",dp[(1<<m)-1]);
    }
    return 0;
}
View Code

 F  樹上毛毛蟲

 其實就是找一條鏈,與這個鏈直接相連的節點儘量的多。

 其實樹形DP,就能夠,咱們維護兩個大的DP值,表明兒子節點中最大的兩個值,dp[i],表明i的子樹中鏈上所鏈接的點儘量的多。

那麼對於每一個節點,維護一個maxx,minn,表明不一樣的兒子節點中,子樹鏈上鍊接的點,最多的和次多的,而後維護一個maxx+minn+son[i]-2+1表示把兩個鏈連在一塊兒,加上當前節點的兒子節點的個數,減去因爲maxx和minn鏈上兩個點是在son裏面,再加上當前節點自己。

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#define LL long long
using namespace std;
const int maxx = 3e5+6;
int ver[maxx*2],Next[maxx*2],head[maxx];
int n,m,tot;
int dp[maxx],son[maxx];
int ans;
void add(int x,int y){
  ver[++tot]=y;Next[tot]=head[x];head[x]=tot;
  ver[++tot]=x;Next[tot]=head[y];head[y]=tot;
  son[x]++;
  son[y]++;
}
void dfs(int u,int fa){
   dp[u]=1;
   int minn=0,maxx=1;
   for (int i=head[u];i;i=Next[i]){
      int v=ver[i];
      if (v==fa)continue;
      dfs(v,u);
      if (maxx<dp[v]){
          minn=maxx;
          maxx=dp[v];
      }else if (minn<dp[v]){
          minn=dp[v];
      }
      dp[u]=max(dp[u],dp[v]+son[u]-1);
   }
   ans=max(minn+maxx+son[u]-1,ans);
}
int main(){
  int uu,vv;
  int t;
  scanf("%d",&t);
  while(t--){
    scanf("%d",&n);
     ans=0;
     for (int i=1;i<=n;i++){
        dp[i]=0;
        head[i]=0;
        son[i]=0;
     }
     for (int i=1;i<=n-1;i++){
        scanf("%d%d",&uu,&vv);
        add(uu,vv);
     }
     dfs(1,0);
     printf("%d\n",ans);
  }
  return 0;
}
View Code
相關文章
相關標籤/搜索