【Educational Codeforces Round 60 (Rated for Div. 2)】 A B C D E

71 篇文章 0 订阅

A

题意 给你一个平均数的定义 问你最长的平均数区间是啥

一开始想复杂了 后来biubiubiu提醒说是找一个最大的数 你向左右蔓延找到一个最长的连续区间并且满足区间内的数都是该最大值即可

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;

#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))

typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
const ll mod =  (int)1e9+7;

ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
const int MAX_N = 200005;
int arr[MAX_N];
int main()
{
    //ios::sync_with_stdio(false);
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    int n ,maxx = -1,ans = 0;
    scanf("%d",&n);
    for(int i = 1;i<=n;++i)
    {
    scanf("%d",&arr[i]);
    if(arr[i]>maxx)
    {
        maxx = arr[i];
    }
    }
    for(int i = 1;i<=n;++i)
    {
        if(arr[i]==maxx)
        {
            int tmp = 1;
            int len_a = 1,len_b = 1;
            while(i-len_a>=1&&arr[i-len_a]==maxx)
            {
                len_a++;
                tmp++;
            }
            while(i+len_b<=n&&arr[i+len_b]==maxx)
            {
                len_b++;
                tmp++;
            }
            i = i + len_b - 1;
            ans = max(tmp,ans);
        }
    }
    printf("%d\n",ans);
    //fclose(stdin);
    //fclose(stdout);
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}


B

题意 n个物品 m次存取次数 一样的最多去k次

很简单 你只要把最大的取k次 然后取一次第二大的 然后继续上述步骤即可

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;

#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))

typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
const ll mod =  (int)1e9+7;

ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
bool cmp(long long a,long long b)
{
    return a >b;
}
long long arr[200025];
int main()
{
    //ios::sync_with_stdio(false);
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    int n,m,k;
    long long ans = 0;
    scanf("%d%d%d",&n,&m,&k);
    for(int i = 1;i<=n;++i) scanf("%lld",&arr[i]);
    sort(arr+1,arr+1+n,cmp);
    int cnt = 0;
    ans+=(m/(k+1))*(k*arr[1]+arr[2]);
    m = m%(k+1);
    ans+=m*(arr[1]);
    printf("%lld\n",ans);
    //fclose(stdin);
    //fclose(stdout);
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}


C

题意 有四个风向 可以让帆船每次移动1 你可以自己移动1步 或者不动

做法 答案具有二分单调性 因为你步数越多 你可以保持不动 所以单调性得证 所以你要预处理前缀和 相当于t天是有t天的贡献 然后看到的地点和重点哈密顿距离是否小于等于时间 t 来check

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;

#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))

typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
const ll mod =  (int)1e9+7;

ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
const int MAX_N = 100025;
char str[MAX_N];
int sum[MAX_N][2];
int main()
{
    //ios::sync_with_stdio(false);
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    int n;
    long long sx,sy,ex,ey;
    scanf("%lld%lld%lld%lld",&sx,&sy,&ex,&ey);
    scanf("%d",&n);
    scanf("%s",str+1);
    for(int i = 1;i<=n;++i)
    {
        if(str[i]=='U')
        {
            sum[i][0] = sum[i-1][0];
            sum[i][1] = sum[i-1][1]+1;
        }
        else if(str[i]=='D')
        {
            sum[i][0] = sum[i-1][0];
            sum[i][1] = sum[i-1][1]-1;
        }
        else if(str[i]=='L')
        {
            sum[i][0] = sum[i-1][0]-1;
            sum[i][1] = sum[i-1][1];
        }
        else if(str[i]=='R')
        {
            sum[i][0] = sum[i-1][0]+1;
            sum[i][1] = sum[i-1][1];
        }
    }
    long long l = 1,r = 1e18;
    while(l<=r)
    {
        long long mid = (l+r)>>1;
        if(abs(sx+mid/n*sum[n][0]+sum[mid%n][0]-ex)+abs(sy+mid/n*sum[n][1]+sum[mid%n][1]-ey)<=mid) r = mid - 1;
        else l = mid + 1;
    }
    if(l>=1e18)
    {
        printf("-1\n");
    }
    else printf("%lld\n",l);
    //fclose(stdin);
    //fclose(stdout);
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}


D

题意 给你n个物品 每个物品占1空间 分开以后占m空间 

问你打到空间n的方案数有多少 首先我们不难推得 dp[1] dp[2] ......dp[m-1] 他们的值都是1

然后 dp[n] = dp[n-1]  + dp[n-m] 我们就不难向到用矩阵快速幂去做了 这样做法是 M^3*logn的 可以过

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;

#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))

typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
const ll mod =  (int)1e9+7;

ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
int M;
const int Mod=1000000007;
struct mat
{
    ll jz[105][105];
};
mat mat_mul(mat x,mat y)
{
    mat res;
    memset(res.jz,0,sizeof(res.jz));
    for(int i=0; i<M; i++)
        for(int k=0; k<M; k++)
            for(int j=0; j<M; j++)
                res.jz[i][j]=(res.jz[i][j]+x.jz[i][k]*y.jz[k][j]+Mod)%Mod;
    return res;
}
ll power_mod (ll P)//.res是系数矩阵,ans是变换矩阵!!左->ans,右->res.!!
{
    mat ans,res;
    res.jz[0][0] = 1;
    res.jz[M-1][0] = 1;
    for(int i = 1;i<M;++i)
        res.jz[i-1][i] = 1;
    for(int i = 0;i<M;++i)
        ans.jz[0][i] = 1;
    ans.jz[0][0] = 2;
    while(P>0)
    {
        if(P&1)
            ans=mat_mul(ans,res);//所以应该答案矩阵在左ans,res);
                P=P>>1;
        res=mat_mul(res,res);
    }
    return (ans.jz[0][0]+Mod)%Mod;//返回指定位置元素
}
int main()
{
    //ios::sync_with_stdio(false);
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    long long n;
    scanf("%lld%d",&n,&M);
    if(n<=M)
    {
        if(n==M)
        {
            printf("2\n");
        }
        else printf("1\n");
    }
    else printf("%lld\n",power_mod(n-M));
    //fclose(stdin);
    //fclose(stdout);
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}

E

题意就是先给你一个串 然后这个串对一个原串做很多变化达到的 问你不超过三次变化能否还原原串

做法 跟别人学的 因为26^3 >10000 所以你用26进制 

构造三个字符串 第一个循环的由 26*26 个 a 到 z 组成

                          第二个循环的由 26 个 a 到 z 组成

                         第三个 由循环的 一个 a 到 z 组成

那么你想知道这个串原来是啥位置 就是第一个串 / 26 /26 %26 的块过来

                                                     在大块确定后 /26 %26 是这个大块的某个26小块过来

                                                    在%26 就是小块里面第几个 那么原来id就知道了

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;

#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))

typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
const ll mod =  (int)1e9+7;

ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
const int MAX_N = 100005;
char s[3][MAX_N];
vector<int > id;
int main()
{
    //ios::sync_with_stdio(false);
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    string a;
    cin >> a;
    int len = a.length();
    string t[3];
    s[0][len] = s[1][len] = s[2][len] = '\0';
    for(int i = 0;i<len;++i)
    {
        s[0][i] = (i%26+'a');
        s[1][i] = (i/26%26 + 'a');
        s[2][i] = (i/(26*26)%26 + 'a');
    }
    for(int i = 0;i<3;++i) cout << "? " << s[i]<<endl,cin >>t[i];
    for(int i = 0;i<len;++i) id.push_back(t[0][i]-'a'+26*(t[1][i]-'a')+26*26*(t[2][i]-'a'));
    char ans[100005];
    for(int j = 0;j<len;++j) ans[id[j]] = a[j];
    ans[len] = '\0';
    cout << "! " << ans << endl;
    //fclose(stdin);
    //fclose(stdout);
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值