2016.11.6 night NOIP模拟赛 考试整理

时间:2023-03-09 17:24:51
2016.11.6 night NOIP模拟赛 考试整理

题目+数据:链接:http://pan.baidu.com/s/1hssN8GG 密码:bjw8
总结:

总分:300分,仅仅拿了120份。

这次所犯的失误:对于2,3题目,我刚刚看就想到了正确思路,急于敲正确思路,而没有去骗基础得分。

结果第二题DP打残了,第三题排列组合漏了一个小点没考虑到,都是仅仅拿了10分。

T1:

 /*
第一题比较容易,注意一些细节就可以了。
比如删除前导0不能删没了等等。
*/
#define N 1500
#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
char a[N],b[N];
int a1[N],b1[N],len;
void input()
{
scanf("%s%s",a+,b+);
len=strlen(a+);
for(int i=;i<=len;++i)
a1[i]=a[i]-'';
for(int i=;i<=len;++i)
b1[i]=b[i]-'';
}
int main()
{
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
input();
for(int i=;i<=len;++i)
{
if(a1[i]>b1[i]) b1[i]=;
if(a1[i]<b1[i]&&b1[i]!=) a1[i]=;
}
int ia=,ib=;
bool flag=false;
while(ia<len&&(a1[ia]==||a1[ia]==))
{
if(a1[ia]==) flag=true;
ia++;
}
if(a1[ia]==) ia++;
if(ia>len&&(!flag)) printf("BOOM");
else{
for(int i=ia;i<=len;++i)
if(a1[i]!=) printf("%d",a1[i]);
if(ia>len&&flag) printf("");
}
printf("\n");
flag=false;
while(ib<len&&(b1[ib]==||b1[ib]==))
{
if(b1[ia]==) flag=true;
ib++;
}
if(b1[ib]==) ib++;
if(ib>len&&(!flag)) printf("BOOM");
else{
for(int i=ib;i<=len;++i)
if(b1[i]!=) printf("%d",b1[i]);
if(ib>len&&flag) printf("");
}
fclose(stdin);
fclose(stdout);
return ;
}

T2:正确做法所用的技巧和NOIP2015Day2子串相同都用到了辅助数组。

哎╮(╯▽╰)╭圆形操场不是成环考虑的。

说明:测试数据中有两组是有问题的,就是当出现偶数组合并不了的时候,是输出了最大值。而zhx大牛的最大值是1e9,因人而异吧。

 #define N 405
#include<iostream>
using namespace std;
#include<cstdio>
#include<cstring>
typedef long long ll;
int n,sum[N];
ll f1[N][N],f2[N][N];
void input()
{
scanf("%d",&n);
int x;
for(int i=;i<=n;++i)
{
scanf("%d",&x);
sum[i]=sum[i-]+x;
}
}
void DP()
{
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
f1[i][j]=f2[i][j]=(<<)-;
for(int i=;i<=n-;++i)
f2[i][i+]=sum[i+]-sum[i-];
for(int i=;i<=n;++i)
f1[i][i]=;
for(int len=;len<=n;++len)
for(int i=;i+len-<=n;++i)
{
int j=i+len-;
for(int k=i;k<j;++k) f2[i][j]=min(f2[i][j],f1[i][k]+f1[k+][j]+sum[j]-sum[i-]);
for(int k=i;k<j;++k) f1[i][j]=min(f1[i][j],f2[i][k]+f1[k+][j]+sum[j]-sum[k]);
/*注意这个推f1这个方程中,所加的代价是sum[j]-sum[k],因为i---k-1,这段石子的花费,我们在推f2的时候已经加过了,所以不能重复加了*/
}
}
int main()
{
freopen("merge.in","r",stdin);
freopen("merge.out","w",stdout);
input();
DP();
cout<<f1[][n]<<endl;
fclose(stdin);
fclose(stdout);
return ;
}

T3:

 #define N 100010
#include<iostream>
using namespace std;
#include<cstdio>
#define mod 1000000007
typedef long long ll;
int n,m,x,y;
bool p1[N],p2[N];
ll jc[N],ny[N];
ll quick_pow(ll a,ll b)//a^b
{
ll ans=;
while(b)
{
if(b&)
{
ans=(ans*a)%mod;
}
a=(a*a)%mod;
b>>=;
}
return ans;
}
ll Mo(ll x)/*这里定义了一个负数的取模方法,因为负数取模还是负数,所以为了预防结果输出这种不合逻辑的答案,我们需要进行如下处理*/
{
if(x>=&&x<mod) return x;
x%=mod;
if(x<) x+=mod;
return x;
}
ll C(int n,int m)
{
if(m>n||m<) return ;
if(m==n||m==) return ;
return jc[n]*ny[m]%mod*ny[n-m]%mod;
}
int main()
{
freopen("problem.in","r",stdin);
freopen("problem.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=;i<=m;++i)
{
scanf("%d%d",&x,&y);
if(x==y)
{
printf("");
return ;
}
p1[x]=true;p2[y]=true;
}
int s=;
for(int i=;i<=n;++i)
{
if(!p1[i]&&!p2[i]) s++;/*统计可以*放的个数*/
}
jc[]=;
for(int i=;i<=n;++i) jc[i]=(jc[i-]*i)%mod;
for(int i=;i<=n;++i) ny[i]=quick_pow(jc[i],mod-);
ll ans=jc[n-m];
for(int i=;i<=s;++i)
{
if(i&) ans=Mo(ans-C(s,i)*jc[n-m-i]);
else ans=Mo(ans+C(s,i)*jc[n-m-i]);
}
cout<<ans<<endl;
fclose(stdin);
fclose(stdout);
return ;
}