Codeforces Round 871

目录

A. Love Story

B. Blank Space

C. Mr. Perfectly Fine

D. Gold Rush

E. The Lakes

F. Forever Winter

G. Hits Different

H. Don’t Blame Me


A. Love Story

直接逐个匹配

string a="codeforces";
void solve()
{
   string s; cin>>s;
   int cnt=0;
   for(int i=0;s[i];i++){
        if(a[i]!=s[i]) cnt++;
   }
   cout<

B. Blank Space


需不需要数组,直接快速判断

void solve()
{
    int cnt=0,now=0;
    cin>>n;
    while(n--){
        int x; cin>>x;
        if(!x) now++;
        else now=0;
        cnt=max(cnt,now);
    }
    cout<

C. Mr. Perfectly Fine


分类讨论注意情况的数量,是否考虑清楚了

void solve()
{
    int A= 1e9, B = 1e9,AB=1e9;
    cin>>n;
    while(n--){
        int x;string op; cin>>x>>op;
        if(op=="01") B=min(B,x);
        else if(op=="10") A=min(A,x);
        else if(op=="11")AB=min(AB,x);
    } 
    int ans=min(A+B,AB);
    cout<<(ans>=1e9 ? -1 : ans)<

D. Gold Rush


简单进制变化注意次数bfs注意处理重复

void solve()
{
    cin>>n>>m;
    map mp;
    queue q;
    q.push(n);
    while(!q.empty()){
        int t=q.front(); q.pop();
        if(mp[t]) continue;
        mp[t]=true;
        if(t==m){
            cout<<"YES"<

E. The Lakes


注意bfs的时候第一个加入的点要st[x][y]=true;
接着就是在加入点的时候就进行判断已经进入了避免多次进入无用点超时


void solve()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>w[i][j],st[i][j]=false;



    auto bfs = [&] (int x,int y){
        queue q;
        q.push({x,y});
        int res=w[x][y];
        st[x][y]=true;
        while(!q.empty()){
            auto [x,y]=q.front(); q.pop();
            int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
            for(int i=0;i<4;i++){
                int a=x+dx[i],b=y+dy[i];
                if(a<1||a>n||b<1||b>m) continue;
                if(st[a][b]) continue;
                if(!w[a][b]) continue;
                res+=w[a][b];
                st[a][b]=true;
                q.push({a,b});
            }
        }
        return res;
    };

    int ans=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(!st[i][j] && w[i][j]){
                ans=max(ans,bfs(i,j));
            }

    cout<

F. Forever Winter


注意题目的特征描述,找到和发现性质即可

void solve()
{
    map mp;
    cin>>n>>m;

    for(int i=1;i<=n;i++) p[i]=0;

    while(m--){
        int a,b; cin>>a>>b;
        p[a]++,p[b]++;
    }

    int root=0,w=0,cnt=0;
    for(int i=1;i<=n;i++){
        if(p[i]==0) continue;// 无用的点
        if(p[i]==1) cnt++;// 最外围的点
        else root++;// 表示根节点和第二层的点
    }
    root--;
    w=cnt/root;
    cout<

G. Hits Different


叠罗汉从上到小一定具有性质注意发现和尝试类似前缀和

LL w[N];

void intn(){
    for(int i=1,t=1;;i++)
        for(int j=1;j<=i;j++,t++){
            if(j==1) w[t]=(LL)t*t+w[t-i+1];
            else if(j==i) w[t]=(LL)t*t+w[t-i];
            else w[t]=(LL)t*t+w[t-i]+w[t-i+1]-w[t-2*i+2];
            if(t>N-5) return ;
        }   
}
void solve()
{
    cin>>n;
    cout<

H. Don’t Blame Me


dp的状态转移如果是方案数很少的我们就可以用状态机模型然后这个数选择或者是不选择带来的收益即可

int dp[65],d[65];

void solve()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];


    // 可以理解为滚动数组
    memset(dp,0,sizeof dp);
    for(int i=1;i<=n;i++){
        memcpy(d,dp,sizeof dp);// 表示上一个状态的方案
        dp[a[i]]+=1;// 表示当前这个数选择它自己
        for(int j=0;j<=64;j++){// 表示在之前数的基础上选择当前这个数带来的收益是什么
            int x=j&a[i];
            (dp[x]+=d[j])%=mod;
        }
    }
    int ans=0;
    for(int i=0;i<=64;i++)
        if(__builtin_popcount(i)==m) (ans+=dp[i])%=mod;

    cout<

你可能感兴趣的:(div4,算法)