Acwing.第131场周赛

Acwing.第131场周赛

比赛链接

A中间数

题目

思路:

简单的模拟

代码:

#include<bits/stdc++.h>
using namespace std;
void solve(){
	int a,b,c;
	cin>>a>>b>>c;
	int ans=a+b+c;
	cout<<ans-max(a,max(b,c))-min(a,min(b,c))<<endl;
	return ;
	
}
int main(){
	int t=1;
	while(t--){
		solve();
	}
	return 0;

}

B奶牛报数

题目

思路:

想到了一个思路,但是有部分测试点没过去
网友们可以帮我看看,有机会我再改一改
更新:我知道是哪里错了,原来是我所写的不是最优策略,我们要求的1号报的数要尽可能的比较小,同时输出和判断最大值时候也出现了一些问题

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+10;
int a[N];
int s[N];
void solve(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        s[i]=s[i-1]+a[i];
    }
    int l1=1;

    for(int i=n+1;i<=n*2;i++){
        a[i]=a[l1++];
        s[i]=s[i-1]+a[i];
    }
    int l,r;
    cin>>l>>r;
    int maxn=0;
    int flag=0;

    for(int i=1;i<=n;i++){
        if(s[i-2+r]-s[i+l-2]>maxn){//这里得写等于>=
            maxn=s[i-2+r]-s[i-2+l];
            flag=i;
        }
    }
    // cout<<flag<<endl;
    // return ;
    
    int sum=1;

    for(int i=flag;;i++){

        if(i%n==1){
            cout<<sum<<endl;
            return ;
        }
        sum++;
    }
    return ;
    
}
signed main(){
    int t=1;
    while(t--){
        solve();
    }
    return 0;

}

接下来让我们看看正确的思路吧:
破环成链,将原串复制一份拼接到后面,则任意一种报数方案都对应新串上一段长度为n的区间,反之亦然。
在新串上枚举起点,用最大区间和更新答案,对于任意起点i属于[2,2+n-1],将区间[1,n]映射到[i,i+n-1],则区间[l,r)就被映射到[i-1+l,i-1+r],然后就可以用到我们之前所求出来的前缀和.

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+10;
int a[N];
int s[N];
void solve(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        s[i]=s[i-1]+a[i];
    }
    int l1=1;

    for(int i=n+1;i<=n*2;i++){
        a[i]=a[l1++];
        s[i]=s[i-1]+a[i];
    }

    int l,r;
    cin>>l>>r;
    int maxn=0;
    int flag=0;

    for(int i=2;i+n-1<=2*n;i++){
        if(s[i-2+r]-s[i+l-2]>=maxn){
            maxn=s[i-2+r]-s[i-2+l];
            flag=i;
        }
    }
    // cout<<flag<<endl;
    // return ;
    
    int sum=1;

    // for(int i=flag;;i++){

    //     if(i%n==1){
    //         cout<<sum<<endl;
    //         return ;
    //     }
    //     sum++;
    // }
    cout<<n+1-(flag-1)<<endl;
    
    return ;
    
}
signed main(){
    int t=1;
    while(t--){
        solve();
    }
    return 0;

}

C制作地图

题目

思路:

这是一个dp问题,可是我巨讨厌dp问题!!!
我直接附上ac代码吧,有知道怎么做的,可以联系教教我

代码:

#include <cstring>
#include <iostream>

using namespace std;

const int N = 1000010, MOD = 1e9 + 7;

int n;
char g[N];
int f[N][2][4];

int id(char c) {
  if (c=='*') return 3;
  return c - '0';
}

int main() {
  scanf("%s", g + 1);
  //输入
  n = strlen(g + 1);//记录长度
  g[n + 1] = '0';


  if (g[1] != '?') f[1][0][id(g[1])] = 1;

  else for (int i = 0; i <= 3; i++) f[1][0][i] = i != 2;

  for (int i = 2; i <= n + 1; i++)
    for (int j = 0; j <= 1; j++)
      for (int k = 0; k <= 3; k++) {
        if (g[i] != '?' && id(g[i]) != k) continue;

        if (!j) {
          for (int x = 0; x <= 1; x++)
            for (int y = 0; y <= 2; y++)
              if (y == (x + (k == 3)))
                f[i][j][k] = (f[i][j][k] + f[i - 1][x][y]) % MOD;
        } else {
          for (int x = 0; x <= 1; x++)
            f[i][j][k] = (f[i][j][k] + f[i - 1][x][3]) % MOD;
        }
      }

  printf("%d", (f[n + 1][0][0] + f[n + 1][1][0]) % MOD);

  return 0;
}
posted @ 2023-11-26 19:57  du463  阅读(12)  评论(0编辑  收藏  举报