Codeforces Global Round 7 A~D2題解

eg:掉分場,D題馬拉車常數爆炸了一直tle,賽後換了種寫法過了。

A

題意:構造出一個長度爲n的數字,使其不爲任意數位的數字的倍數。
題解:若干個2最後加個9,9的倍數是各個數位的數字之和爲9的倍數,如果前面若干個2之和是9的倍數的話換個2成4就好了。

#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const ll mod=998244353;
const int inf=0x3f3f3f3f;
const ll INF=1e12;
const double eps=1e-6;
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int x;
        scanf("%d",&x);
        if(x==1)puts("-1");
        else{
            int y=(x-1)*2;
            if(y%9==0){
                for(int i=1;i<x-1;i++)printf("2");
                puts("49");
            }else {
                for(int i=1;i<x;i++)printf("2");
                puts("9");
            }
        }
    }
    return 0;
}

B

題意:給出一個長度爲n的數組b和x,對於每一個i都有bi=aixib_i=|a_i-x_i|xi=max(a1,,ai1)x_i=max(a_1,…,a_{i-1}),求原數組a。
題解:On反推就行了,比A簡單

#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const ll mod=998244353;
const int inf=0x3f3f3f3f;
const ll INF=1e12;
const double eps=1e-6;
int n,a[maxn],b[maxn];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&b[i]);
    int x=0;
    a[1]=b[1];
    for(int i=2;i<=n;i++){
        x=max(x,a[i-1]);
        a[i]=b[i]+x;
    }
    for(int i=1;i<n;i++)printf("%d ",a[i]);
    printf("%d\n",a[n]);
    return 0;
}

C

題意:給出長度爲n的排列,將其劃分爲k組,求每組的最大值之和和能求到該種最大值的劃分數。
題解:答案是顯然的從大到小取k個數,其和就是第一個問題的答案。劃分的種類數就是每個位置差的乘積。
反思:忘開longlong wa了一發,忘取模wa了一發,真傻

#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const ll mod=998244353;
const int inf=0x3f3f3f3f;
const ll INF=1e12;
const double eps=1e-6;
string s,ans;
int n,k,b[maxn];
struct arr{
    int val,rk;
}a[maxn];
bool cmp(arr a,arr b){
    return a.val<b.val;
}
int main(){
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)scanf("%d",&a[i].val),a[i].rk=i;
    ll ans=0;
    sort(a+1,a+1+n,cmp);
    for(int i=n,j=1;i>=1,j<=k;i--,j++)
        ans=ans+1ll*a[i].val;
    for(int i=n,j=1;i>=1,j<=k;i--,j++)
        b[j]=a[i].rk;
    sort(b+1,b+1+k);
    ll cnt=1;
    for(int i=2;i<=k;i++)
        cnt=cnt*(1ll*abs(b[i]-b[i-1]))%mod;
    printf("%lld %lld\n",ans,cnt);
    return 0;
}

D

題意:給定字符串s,找一個前綴和一個後綴使其拼接起來爲一個迴文串。D1長度爲5000 D2長度爲1000000
題解:D1暴力亂搞即可,D2哈希 馬拉車 迴文自動機也可以。將問題拆成兩步,第一步原串左右找相同部分,假設找完之後左右指針分別爲L和R,那麼就從L和R各找一個迴文串,取一個最長的即爲答案。
D1廢物暴力代碼

#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const ll mod=998244353;
const int inf=0x3f3f3f3f;
const ll INF=1e12;
const double eps=1e-6;
string s,ans;
bool check(string t){
    int l=0,r=t.length()-1;
    while(l<r){
        if(t[l]==t[r])l++,r--;
       else  return false;
    }
    return true;
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        cin>>s;ans.clear();
        string px,sx;
        px.clear();sx.clear();
        int len=s.length();
        if(len==1)cout<<s<<endl;
        else{
            int l=0,r=len-1;
            while(l<r){
                px.push_back(s[l]);
                sx.push_back(s[r]);
                if(px==sx)l++,r--;
                else break;
            }
            if(px[px.length()-1]!=sx[sx.length()-1])px.pop_back(),sx.pop_back();
            if(l>r){
                ans=px;
                reverse(sx.begin(), sx.end());
                ans=ans+sx;
            }else{
                string sum,num;sum.clear();num.clear();
                for(int i=l;i<=r;i++){
                    sum.push_back(s[i]);
                    if(check(sum)){
                        if(sum.length()>num.length())num=sum;
                    }
                }
                sum.clear();
                for(int i=r;i>=l;i--){
                    sum.push_back(s[i]);
                    if(check(sum)){
                        if(sum.length()>num.length())num=sum;
                    }
                }
                ans=px;
                ans=ans+num;
                reverse(sx.begin(), sx.end());
                ans=ans+sx;
            }
            cout<<ans<<endl;
        }
    }
    return 0;
}

D2代碼

#include "stdio.h"
#include "string.h"
#include "string"
#include "iostream"
#include "algorithm"
#include "vector"
#include "queue"
#include "math.h"
#include "map"
#include "stack"
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
const ll mod=998244353;
const int inf=0x3f3f3f3f;
const ll INF=1e12;
const double eps=1e-6;
char s[2*maxn],ss[maxn];
int n,p[2*maxn];
void manacher(){
    for(int i=n*2;i>1;i--){
        if(i&1)s[i]='@';
        else s[i]=s[i>>1];
    }
    s[1]=s[2*n+1]='#';
    n=2*n+1;
    p[1]=1;
    int mx=1,id=1;
    for(int i=2;i<=n;i++){
        if(i<=mx){
            p[i]=min(p[2*id-i],mx-i+1);
        }
        else p[i]=1;
        while(i+p[i]<=n&&i-p[i]>=1&&s[i+p[i]]==s[i-p[i]])p[i]++;
        if(mx<i+p[i]-1){
            mx=i+p[i]-1;
            id=i;
        }
    }
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%s",ss+1);
        n=strlen(ss+1);
        int m=n;
        int l=1;
        while(l<=n/2&&ss[l]==ss[n-l+1])l++;
        if(l*2>n){
            printf("%s\n",ss+1);
            continue;
        }
        for(int i=1;i<=n-2*(l-1);i++)s[i]=ss[l+i-1];
        n-=2*(l-1);
        s[n+1]='\0';
        manacher();
        int pos=0;
        for(int i=1;i<=n;i++){
            if(p[i]==i-1&&p[i]>p[pos])    pos=i;
            if(p[i]==n-i&&p[i]>p[pos])    pos=i;
        }
        for(int i=1;i<l;i++)    putchar(ss[i]);
        for(int i=pos-p[pos]+1;i<=pos+p[pos]-1;i++)
          if(s[i]>='a'&&s[i]<='z')    putchar(s[i]);
        for(int i=m-l+2;i<=m;i++)    putchar(ss[i]);
        putchar('\n');
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章