2007提高
A.统计数字(模拟)
B.字符串的展开(模拟)
C.矩阵取数游戏(dp+高精度)
考虑倒着dp,dp[i][j]表示还剩i…j的数,把这些取走的最大得分。决策无非两种,先拿i,先拿J.
D. 树网的核(树的直径+贪心+暴力枚举)
n=300,各种瞎搞。如果只能选一个点的话,一定选中心最优,因此我们以中心为根,贪心的去扩展。每次看能不能把最远的点干掉。。不能时就是答案了。
A
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 200010
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,a[N],ans[N],cnt[N],num=0;
int main(){
// freopen("a.in","r",stdin);
n=read();for(int i=1;i<=n;++i) a[i]=read();sort(a+1,a+n+1);a[0]=-1;
for(int i=1;i<=n;++i){
if(a[i]!=a[i-1]) ans[++num]=a[i],cnt[num]=1;
else cnt[num]++;
}for(int i=1;i<=num;++i) printf("%d %d\n",ans[i],cnt[i]);
return 0;
}
B
#include<cstdio>
#include<cstring>
int p1,p2,p3,k=0;
char str[101],ans[10000];
void work(int x,int y){
int p=0;
if(x>='a'&&x<='z'&&y>='a'&&y<='z') p=1;
if(x>='0'&&x<='9'&&y>='0'&&y<='9') p=2;
if(!p||x>=y){ans[++k]='-';return;}
if(x+1==y) return;
if(p3==1){
if(p1==1||(p1==2&&p==2))
for(int i=x+1;i<y;++i)
for(int j=1;j<=p2;++j) ans[++k]=i;
if(p1==2&&p==1)
for(int i=x-32+1;i<y-32;++i)
for(int j=1;j<=p2;++j) ans[++k]=i;
if(p1==3)
for(int i=x+1;i<y;++i)
for(int j=1;j<=p2;++j) ans[++k]='*';
}else{
if(p1==1||(p1==2&&p==2))
for(int i=y-1;i>x;--i)
for(int j=1;j<=p2;++j) ans[++k]=i;
if(p1==2&&p==1)
for(int i=y-32-1;i>x-32;--i)
for(int j=1;j<=p2;++j) ans[++k]=i;
if(p1==3)
for(int i=y-1;i>x;--i)
for(int j=1;j<=p2;++j) ans[++k]='*';
}
}
int main(){
//freopen("a.in","r",stdin);
scanf("%d%d%d%s",&p1,&p2,&p3,&str);
for(int j=0;str[j]!=0;++j)
if(str[j]=='-') work(str[j-1],str[j+1]);
else ans[++k]=str[j];
printf("%s",ans+1);
return 0;
}
C
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,m,w[N];
struct bigint{
int a[50],n;
bigint(){memset(a,0,sizeof(a));n=0;}
friend bigint operator+(bigint x,bigint y){
bigint res;res.n=max(x.n,y.n);
for(int i=1;i<=res.n;++i) res.a[i]=x.a[i]+y.a[i];
for(int i=1;i<=res.n;++i) res.a[i+1]+=res.a[i]/10,res.a[i]%=10;
if(res.a[res.n+1]) res.n++;return res;
}
friend bigint operator*(bigint x,int y){
bigint res;res.n=x.n;
for(int i=1;i<=res.n;++i) res.a[i]=x.a[i]*y;
for(int i=1;i<=res.n;++i) res.a[i+1]+=res.a[i]/10,res.a[i]%=10;
while(res.a[res.n+1]) res.n++,res.a[res.n+1]+=res.a[res.n]/10,res.a[res.n]%=10;
return res;
}
}ans,bin[N];
inline bigint max(bigint x,bigint y){
if(x.n>y.n) return x;if(x.n<y.n) return y;
for(int i=x.n;i>=1;--i){
if(x.a[i]>y.a[i]) return x;
if(x.a[i]<y.a[i]) return y;
}return x;
}
int main(){
// freopen("a.in","r",stdin);
m=read();n=read();bin[0].a[1]=1;bin[0].n=1;
for(int i=1;i<=80;++i) bin[i]=bin[i-1]*2;
while(m--){
for(int i=1;i<=n;++i) w[i]=read();bigint dp[N][N];
for(int i=1;i<=n;++i) dp[i][i]=bin[n]*w[i];
for(int len=2;len<=n;++len)
for(int i=1;i+len-1<=n;++i){
int j=i+len-1;
dp[i][j]=max(dp[i+1][j]+bin[n-len+1]*w[i],dp[i][j-1]+bin[n-len+1]*w[j]);
}ans=ans+dp[1][n];
}for(int i=ans.n;i>=1;--i) putchar(ans.a[i]+'0');return 0;
}
D
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 310
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,s,h[N],num=0,dis[N],fa[N],dep[N],res=1,rt=1,d=0,len=0,du[N];
bool inq[N];
struct edge{
int to,next,val;
}data[N<<1];
void dfs(int x){
for(int i=h[x];i;i=data[i].next){
int y=data[i].to;if(fa[x]==y) continue;
fa[y]=x;dis[y]=dis[x]+data[i].val;
if(dis[y]>dis[res]) res=y;dfs(y);
}
}
void dfs1(int x){
for(int i=h[x];i;i=data[i].next){
int y=data[i].to;if(fa[x]==y) continue;
fa[y]=x;dis[y]=dis[x]+data[i].val;dep[y]=dep[x]+1;
if(dis[y]>dis[res]) res=y;dfs1(y);
}
}
void dfs2(int x){
for(int i=h[x];i;i=data[i].next){
int y=data[i].to;if(fa[x]==y) continue;
dis[y]=dis[x]+data[i].val;dfs2(y);
}
}
int main(){
// freopen("a.in","r",stdin);
n=read();s=read();
for(int i=1;i<n;++i){
int x=read(),y=read(),val=read();
data[++num].to=y;data[num].next=h[x];h[x]=num;data[num].val=val;
data[++num].to=x;data[num].next=h[y];h[y]=num;data[num].val=val;
}dfs(1);rt=res;fa[rt]=0;dis[rt]=0;dfs(rt);d=dis[res];
//如果只能选一个点的话,一定选中心最优,因此我们以中心为根,贪心的去扩展
while(res!=rt){if(dis[fa[res]]<=d/2) break;res=fa[res];}
int dx=dis[res]-d/2,dy=d/2-dis[fa[res]];if(dx<=dy) rt=res;else rt=fa[res];
fa[rt]=0;dis[rt]=0;res=rt;inq[res]=1;du[res]=0;dfs1(rt);
while(1){
for(int i=1;i<=n;++i) if(dis[i]>dis[res]) res=i;
int ans=dis[res];if(!ans){puts("0");return 0;}
while(!inq[fa[res]]) res=fa[res];
if((fa[res]==rt?du[fa[res]]>=2:du[fa[res]]>=1)||len+dis[res]>s){printf("%d\n",ans);return 0;}
du[fa[res]]++;inq[res]=1;len+=dis[res];dis[res]=0;dfs2(res);
}return 0;
}