您的位置:首页 > 其它

纪中训练 day9 【NOIP普及组】模拟赛D组 解题报告

2018-02-02 16:27 399 查看
目录

☞第一题 公牛数学☜
大意

思路

代码

☞第二题 愤怒的牛☜
大意
范围

思路

代码

☞第三题 约数和☜
大意
范围

思路

代码(没加线性筛素数)

☞第四题 旅行☜
大意

思路

代码

☞第五题 逆序统计☜
大意
范围

思路

代码

☞第一题 公牛数学☜

大意

计算两个数的乘积(均小于等于10^30次方)。

思路

直接高精乘,模板题目。

代码

#include<bits/stdc++.h>
#define r(i,a,b) for(int i=a;i<=b;i++)
#define d(i,a,b) for(int i=a;i>=b;i--)
using namespace std;string s;
int a[101],b[101],c[201],len1,len2;
int main()
{
freopen("bullmath.in","r",stdin);
freopen("bullmath.out","w",stdout);
cin>>s;len1=s.size();//输入第一个字符串
r(i,0,len1-1) a[100-i]=s[len1-i-1]-48;//转换
cin>>s;len2=s.size();//输入第二个字符串
r(i,0,len2-1) b[100-i]=s[len2-i-1]-48;//转换
int g=0;
d(i,100,1)
d(j,100,1)//高精乘
{
c[i+j]+=a[i]*b[j];
c[i+j-1]+=c[i+j]/10;
c[i+j]%=10;
}
int j=1;
while(!c[j]) j++;//处理0
r(i,j,200)
printf("%d",c[i]);//输出
}


☞第二题 愤怒的牛☜

大意

N个房间,C头牛,使它们间隔距离最大,求最小间隔距离。

范围

2<=N<=100,000

0<=xi<=1,000,000,000(房间的位置)

2<=C<=N 牛的个数

思路

二分答案+排序

代码

#include<bits/stdc++.h>
#define r(i,a,b) for(int i=a;i<=b;i++)
using namespace std;int n,m,a[1000001],l,r,mid,k,sum=1;
bool check(int wh)//判断当间隔数为x时能否放的数量能否超过过m头牛
{
sum=1;
r(i,2,n)
if(a[i]>=k)//可以放
{
sum++;//放进去
k=a[i]+wh;//更新
}
return sum>=m;//能放或放不下
}
int main()
{
freopen("aggr.in","r",stdin);
freopen("aggr.out","w",stdout);
scanf("%d %d",&n,&m);
r(i,1,n) scanf("%d",&a[i]);
stable_sort(a+1,a+1+n);//排序
l=0;r=a
;//初始化
while(l<=r)//二分答案
{
mid=(l+r)>>1;k=mid+a[1];
if(check(mid)) l=mid+1;else r=mid-1;
}
printf("%d",l-1);//因为之前加了一所以要减
}


☞第三题 约数和☜

大意

有t个数,求每个数约数的和。

范围

对于20%的数据, T=1.

对于50%的数据: T<=5000;

对于80%的数据 T<=50000;

对于100%的数据 T<=500000;N<=5000000;

思路

数组保存答案+平方根优化(+线性筛素数)括号内可有可无。

数组保存答案就是用一个数组保存每个数的答案。

平方根优化是根据因数成对出现的原理,但要注意完全平方数。

线性筛素数是因为素数只有1和它本身两个因数,节省循环。

代码(没加线性筛素数)

#pragma GCC optimize(2)//02优化,在NOI等竞赛中不允许使用,这里只是为了方便验证答案,慎用!
#include<cstdio>
#include<cmath>//平方根需要用到cmath库
using namespace std;int n,ans,t,m,gs[5000010];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);ans=0;
if(gs
) {printf("%d\n",gs
);continue;}//数组保存答案的好处
for(int i=1;i<=floor(sqrt(n));++i)
if(n%i==0)//是它的因数
{ans+=i;if(i!=n/i) ans+=n/i;}//成对出现,注意处理完全平方数
gs
=ans;//保存
printf("%d\n",ans);//输出
}
}


☞第四题 旅行☜

大意

有一条7000km长的路,途中有固定的13家旅店和可能会有的20家旅店(位置各不相同),问假设一天只能行驶X公里,B>=X>=A,问共有多少种旅行方案。

思路

后面旅店的方案数=前面距离满足旅店的方案数+本身

代码

#include<bits/stdc++.h>
#define r(i,a,b) for(int i=a;i<=b;i++)
using namespace std;int A,B,n,m=7000,last,now,i;
int w[51];
int ans[7001];
int main()
{
scanf("%d %d",&A,&B);
scanf("%d",&n);i=0;
w[i++]=0;
w[i++]=990;
w[i++]=1010;
w[i++]=1970;
w[i++]=2030;
w[i++]=2940;
w[i++]=3060;
w[i++]=3930;
w[i++]=4060;
w[i++]=4970;
w[i++]=5030;
w[i++]=5990;
w[i++]=6010;
w[i++]=7000;//初始化
while(n--) scanf("%d",&w[i++]);//输入
sort(w,w+i);//排序
ans[0]=1;//初始化
r(j,0,i-1)
r(k,0,j-1)
{
int dis=w[j]-w[k];
if(dis<=B&&dis>=A) ans[j]+=ans[k];//满足要求
}
printf("%d",ans[i-1]);//输出
}


☞第五题 逆序统计☜

大意

有1,2,3,4……N-1,N个数,问在他们全排列中,逆序对为K的个数。

范围

(N<=100,K<=N*(N-1)/2)

思路

先自己暴力打表,然后找规律就行了。

代码

#include<bits/stdc++.h>
#define r(i,a,b) for (int i=a;i<=b;i++)
using namespace std;int n,m;
int f[2][5001];//压缩数组
int main()
{
scanf("%d %d",&n,&m);
f[0][0]=1;//初始化
r(i,1,n)
r(j,0,m)
if(j)
if(j>=i)
f[i&1][j]=(f[(i+1)&1][j]%10000+f[i&1][j-1]%10000-f[(i+1)&1][j-i]%10000)%10000;
else
f[i&1][j]=(f[(i+1)&1][j]%10000+f[i&1][j-1]%10000)%10000;
else
f[i&1][j]=f[(i+1)&1][j]%10000;//三种情况
f[n&1][m]=(f[n&1][m]+10000)%10000;//处理负数
printf("%d",f[n&1][m]);//输出
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: