[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));
}