0
点赞
收藏
分享

微信扫一扫

2018年全国多校算法寒假训练营练习比赛(第二场)A B D E F G H


A ​​吐泡泡​​

自左到右,循环修改。

  1. 代码:

#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
using namespace std;
int v[200];
int main()
{
char s[150];
while(~scanf("%s",s))
{int len,cnt;
len=strlen(s);
memset(v,0,sizeof(v));
for(int i=0;i<len;i++)v[i]=1;
while(1)
{
char qian='q';
int qia=0;
for(int i=0;i<len;i++)
{
if(v[i])
{
if(qian==s[i]&&s[i]=='o'){s[i]='O';v[qia]=0;v[i]=1;break;}
else if(qian==s[i]&&s[i]=='O'){v[qia]=0;v[i]=0;break;}
qian=s[i];
qia=i;
}
}
int l=1;
qian='q';
qia=0;
for(int i=0;i<len;i++)
{
if(v[i])
{
if(qian==s[i])l=0;
qian=s[i];
qia=i;
}
}
if(l)break;
}
for(int i=0;i<len;i++)
{
if(v[i]){cout<<s[i];}
}
cout<<endl;



}
return 0;
}


​​TaoTao要吃鸡​​ 


01背包扩容

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int dp[110][220][2];
int main()
{
int n,m,h;
int q,w;
while(scanf("%d",&n)&&n)
{
scanf("%d%d",&m,&h);
int ans=0;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&q,&w);
for(int j=0;j<=m+h;j++)
{
dp[i][j][0]=dp[i-1][j][0];
if(j+q<=m+h)dp[i][j][0]=max(dp[i][j][0],dp[i-1][j+q][0]+w);
ans=max(ans,dp[i][j][0]);
}
if(h)
{
for(int j=1;j<=m+h;j++)
{
dp[i][j][1]=dp[i-1][j][1];
dp[i][j][1]=max(dp[i][j][1],dp[i-1][j][0]+w);
if(j+q<=m+h)dp[i][j][1]=max(dp[i][j][1],dp[i-1][j+q][1]+w);
ans=max(ans,dp[i][j][1]);
}
}
}
printf("%d\n",ans);
}
return 0;
}

D

​​YB要打炉石​​

最长上升子序列

代码:

#include <iostream>

using namespace std;

int main()
{int n,ma=0,sum=0;
int a[1001]={0},b[1001]={0};
b[1]=1;
cin>>n;
for(int i=1;i<=n;i++)
{cin>>a[i];}
for(int i=2;i<=n;i++)
{
ma=0;
for(int t=1;t<i;t++)
{if(a[i]>=a[t]){
if(b[t]>ma){ma=b[t];}

}

}
b[i]=ma+1;
}

for(int i=1;i<=n;i++)
{if(sum<b[i])sum=b[i];
}
if(sum>=30)cout<<"yes"<<endl;
else cout<<"no"<<endl;
return 0;
}

E

​​小G有一个大树​​

树形dp求树的重心

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>

using namespace std;

int n;
int d[50005];
int dp[50005];
int head[50005];
int minshu;
int ans;
struct shu
{
int v;
int next;
}tr[100005];
void add(int q,int w)
{
tr[ans].v=w;
tr[ans].next=head[q];
head[q]=ans++;

}
void dfs(int x,int pa)
{
d[x]=1;
int maxshu=-1000000;
for(int i=head[x];i!=-1;i=tr[i].next)
{
int son=tr[i].v;
if(son!=pa)
{
dfs(son,x);
d[x]+=d[son];
maxshu=max(maxshu,d[son]);
}
}
dp[x]=max(maxshu,n-d[x]);
minshu=min(dp[x],minshu);

}
int main()
{

while(~scanf("%d",&n))
{
memset(dp,0,sizeof(dp));
memset(d,0,sizeof(d));
memset(head,-1,sizeof(head));
ans=0;
for(int i=1;i<n;i++)
{
int q,w;
scanf("%d%d",&q,&w);
add(q,w);
add(w,q);
}

minshu=10000000;
dfs(1,-1);
for(int i=1;i<=n;i++)
{
if(dp[i]==minshu)
{
printf("%d ",i);
}
}
cout<<minshu<<endl;

}
return 0;
}

F

​​德玛西亚万岁​​

数位dp,怎么种小麦的原题

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define mod 100000000
#define ma 14
int dp[ma][1<<ma],st[ma];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(st,0,sizeof(st));
for(int i=1;i<=n;i++)
{
for(int j=0;j<m;j++)
{
int a;
scanf("%d",&a);
st[i]|=a<<j;//记录每一行的状态
}

}
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<=n;i++)//枚举行
{
for(int j=0;j<(1<<m);j++)//枚举本行状态
{
if((j&st[i])==j&&((j&(j>>1))==0))//条件 :该状态被本行状态包含 该行每个玉米都间隔1以上
{
for(int k=0;k<(1<<m);k++)//枚举上一行状态
{
if((j&k)==0)//两行的状态没有接触的
{
dp[i][j]=(dp[i-1][k]+dp[i][j])%mod;
}
}
}
}

}
int ans=0;
for(int i=0;i<(1<<m);i++)
{
ans=(dp[n][i]+ans)%mod;
}
printf("%d\n",ans);
}
return 0;
}

G

​​送分了QAQ​​


状态压缩dp,类似求包含49 的题。

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int a[30];
long long dp[30][20][15];

long long sove(int pos,int qian,int bb,int limit)
{
if(pos==-1)return bb;
if(!limit&&dp[pos][qian][bb]!=-1)return dp[pos][qian][bb];
long long sum=0;
int end=limit?a[pos]:9;
for(int i=0;i<=end;i++)
{
if((qian==3&&i==8)||i==4)sum+=sove(pos-1,i,1,limit&&(i==a[pos]));
else sum+=sove(pos-1,i,bb,limit&&(i==a[pos]));
}
if(!limit)dp[pos][qian][bb]=sum;
return sum;
}

long long go(long long x)
{
int pos=0;
while(x)
{
a[pos++]=x%10;
x/=10;
}

return sove(pos-1,0,0,1);
}
int main()
{
int n,m;

while(~scanf("%d%d",&n,&m)&&(n+m))
{

memset(dp,-1,sizeof(dp));
memset(a,0,sizeof(a));

printf("%lld\n",go(m)-go(n-1));
}
return 0;
}

H

​​了断局​​

递推一个数列,类似斐波那契数列。

代码:

#include <iostream>
#include <cstdio>
using namespace std;
long long a[60];
void q()
{
a[1]=0;
a[2]=1;
a[3]=1;
for(int i=4;i<=55;i++)
{
a[i]=a[i-1]+a[i-2]+a[i-3];
}
}
int main()
{
int n;
q();
while(~scanf("%d",&n))
{
printf("%lld\n",a[n]);
}
return 0;
}




举报

相关推荐

0 条评论