[Educational Codeforces Round 59 (Rated for Div. 2)]

nothing to say.

A

水题
#include<iostream>
#include<algorithm>
#include<cstdio>

using namespace std;
char s[355];
int q;
int n;
int main() {
    scanf("%d",&q);
    while(q--) {
        scanf("%d %s",&n,&s[1]);
        if(n>2) {
            puts("YES");
            printf("2\n%c ",s[1]);
            for(int i=2;i<=n;i++) putchar(s[i]);
            puts("");
        } else {
            if(s[1]<s[2]) {
                puts("YES");
                printf("2\n%c %c\n",s[1],s[2]);
                puts("");
            }
            else puts("NO");
        }
    }
}

B

水题
#include<iostream>
#linclude<algorithm>
#include<cstdio>
#include<cmath>

typedef long long ll;
ll k,x;
int main() {
    ll q; 
    scanf("%I64d",&q);
    while(q--) {
        scanf("%I64d%I64d",&k,&x);
        printf("%I64d\n",1ll*(k-1)*9ll+x);
    }
}

C

水题
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<queue>
#include<vector>
typedef long long ll;
using namespace std;
const int maxn = 2e5+5;
ll n,k;
ll a[maxn];
char s[maxn];
ll ans;
priority_queue<ll,vector<ll>,greater<ll> >q;
int main() {
    scanf("%I64d%I64d",&n,&k);
    for(int i=1;i<=n;i++) {
        scanf("%I64d",&a[i]);
    }
    scanf("%s",&s[1]);
    for(ll i=1;i<=n;i++) {
        if(s[i]!=s[i-1]) {
            while(q.size()) {
                ans += q.top(); q.pop();
            }
        }
        q.push(a[i]);
        while(q.size()>k) q.pop();
    }
    while(q.size()) {
        ans += q.top(); q.pop();
    }
    printf("%I64d",ans);
}

D

水题
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>

using namespace std;

char buf[1<<20],*p1,*p2;
#define GC (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?0:*p1++)
inline int R()
{
    char t=GC;
    int x=0;
    while(233){
        if( (t>='0'&&t<='9') || (t<='Z'&&t>='A') ) break;
        t=GC;
    } 
    if(t>='0'&&t<='9') return t-'0';
    return t-'A'+10;
}
int n;
int a[5205][5205],sm[5205][5205];
int gg(int xa,int ya,int xb,int yb) {
    return sm[xb][yb] - sm[xa-1][yb] - sm[xb][ya-1] + sm[xa-1][ya-1];
}
bool isok(int cc) {
    int fk = cc*cc;
    for(int i=1;i<=n;i+=cc) {
        for(int j=1;j<=n;j+=cc) {
            int now = gg(i,j,i+cc-1,j+cc-1);
            if(now!=fk&&now!=0) return 0;
        }
    }
    return 1;
}
int ans = 1;
int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j+=4) {
            int o = R();
            a[i][j+3] = o&1;
            a[i][j+2] = (o>>1)&1;
            a[i][j+1] = (o>>2)&1;
            a[i][j] = (o>>3)&1;
        }
    }
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n;j++) {
            sm[i][j] = sm[i-1][j] + sm[i][j-1] - sm[i-1][j-1] + a[i][j];
        }
    }
    int o = n;  
    if(isok(n)) ans = n;
    for(int i=2;i*i<=o;i++) {
        if(o%i==0) {
            if(ans<i) {
                if(isok(i)) ans = i;
            }
            if(i*i!=o&&ans<(n/i)) {
                if(isok(n/i)) ans = n/i;
            }
        }
    }
    printf("%d",ans);   
}

E

n 100,一个01字符串,每次可以消除一段数字相同的区间,可以获得区间长度对应的价值(不保证长度越大价值越大),消除之后两边合在一起。求可以得到的最大价值。 dp状态f[i][j][pre]表示讨论到区间[i,j],包括i和i前面和i相同得字符串的长度(这个状态难以想到因为他状态不只是包含在区间内)。 这样就有依赖于dfs的转移,枚举跨过中间一段和后面的连接起来或者切断字符串来转移。具体look code:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define int long long
using namespace std;
int  n;
char s[110];
int f[110][110][110];

int a[110];
int dfs(int x,int y,int prelen) {
    if(x>y) return 0;
    if(f[x][y][prelen]!=-1) return f[x][y][prelen];
    if(x==y) return a[prelen];
    int sm = dfs(x+1,y,1) + a[prelen];
    for(int i=x+1;i<=y;i++) {
        if(s[i]==s[x]) sm = max(dfs(x+1,i-1,1)+dfs(i,y,prelen+1),sm);
    }
    return f[x][y][prelen] = sm;
}
main() {
    scanf("%I64d%s",&n,&s[1]);
    for(int i=1;i<=n;i++) {
        scanf("%I64d",&a[i]);
    }
    memset(f,-1,sizeof f);
    printf("%I64d",dfs(1,n,1));
}
posted @ 2019-01-30 17:01  Newuser233  阅读(6)  评论(0)    收藏  举报