您的位置:首页 > 其它

【XJOI-NOIP16提高模拟训练9】题解。

2016-07-19 21:06 363 查看
http://www.hzxjhs.com:83/contest/55

说实话这次比赛真的很水。。然而我只拿了140分,面壁反思。

第一题:



发现数位和sum最大就是9*18,k最大1000,那么sum*k最大不过2*10^5,若能被x整除,则x也不超过200000,暴力即可。

不知道学军OIlonglong用%I64d还是%lld输入,用了%I64d爆零。。改成lld就AC了。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;

typedef long long LL;

int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
LL l,r;
int k,ans=0;
scanf("%lld%lld%d",&l,&r,&k);
for(int i=1;i<=200000;i++)
{
if(i>r || i<l) continue;
int sum=0,x=i;
while(x)
{
sum+=x%10;
x/=10;
}
if((sum*k%i)==0) ans++;
}
printf("%d\n",ans);
}
return 0;
}


第二题



原本用了矩阵乘法来表示i到j走2^k步有多少种方案,方案数>=1就建一条边,最后跑最短路。。超时,50分。

然后发现自己真的好傻逼。。

直接看代码吧。就是一个简单DP,c[i][j][k]表示i到j走2^k步是否可以,d[i][j]表示i到j最少时间。

if d[i][l][k-1]==1 && d[l][j][k-1]==1 --> d[i][j][k]=1

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;

typedef long long LL;
const int N=60,M=11000;
int n,m,d

;
bool c

[70];

int minn(int x,int y){return x<y ? x:y;}

int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d%d",&n,&m);
memset(c,0,sizeof(c));
memset(d,63,sizeof(d));
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
d[x][y]=1;
c[x][y][0]=1;
}
for(int k=1;k<=64;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int l=1;l<=n;l++)
{
if(c[i][l][k-1] && c[l][j][k-1])
{
d[i][j]=1;
c[i][j][k]=1;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int l=1;l<=n;l++)
{
d[i][j]=minn(d[i][j],d[i][l]+d[l][j]);
}
printf("%d\n",d[1]
);
return 0;
}


第三题



直接递归。

作死用了树状数组维护前缀和,用个数组就好了吧。。

用树状数组超时90分,改成数组就A了。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;

const int N=1100;
char s
;
int n,c
,d

[2];

int lowbit(int x){return x&(-x);}
void add(int x,int d){
for(int i=x;i<=n;i+=lowbit(i)) c[i]+=d;
}
int getsum(int x){
int ans=0;
for(int i=x;i>=1;i-=lowbit(i)) ans+=c[i];
return ans;
}

bool check(int l,int r,int tmp)
{
if(d[l][r][tmp]!=-1) return d[l][r][tmp];
if(l>r) return 0;
if((getsum(r)-getsum(l-1))&1) return d[l][r][tmp]=0;
if(tmp==0)
{
if(l==r && s[l]=='0') return d[l][r][tmp]=1;
if(s[l]=='1' && s[r]=='1' && check(l+1,r-1,1)) return d[l][r][tmp]=1;
return d[l][r][tmp]=0;
}
else
{
int t=getsum(l-1);
for(int i=l;i<r;i++)
{
if((getsum(i)-t)&1) {d[l][i][0]=d[i+1][r][0]=0;continue;}
if(check(l,i,0) && check(i+1,r,0)) return d[l][r][tmp]=1;
}
return d[l][r][tmp]=0;
}
}

int main()
{
freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
scanf("%s",s+1);
memset(c,0,sizeof(c));
memset(d,-1,sizeof(d));
for(int i=1;i<=n;i++)
if(s[i]=='1') add(i,1);
if(check(1,n,0)) printf("YES\n");
else printf("NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: