这次没什么话可以闲侃…..
这些题目都不水…..
第一题
其实就是说把正数乘起来,负数成对儿乘罢了
还有特判,当整个数列中只有一个数的时候,输出这个数
#include <iostream>
#include <cstdio>
using namespace std;
int n,i,a[20],l,f,m=-10;
long long s=1;
int main()
{
freopen("max.in","r",stdin);
freopen("max.out","w",stdout);
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
if (n==1)
{
printf("%d",a[1]);
return 0;
}
for (i=1;i<=n;i++)
{
if (a[i]!=0) s*=a[i];
else
l++;
if (a[i]<0)
{
m=max(m,a[i]);
f++;
}
}
if (s<0) s/=m;
if (f%2==0) printf("%lld",s);
else
if (l+f==n&&f<n) printf("%d",0);
else
printf("%lld",s);
}
第二题
给你一些火柴棍拼成的数字,然后组成同样位数,同样棍数的最大数
刚开始我一下就想到了DFS,结果….看数据自行体会
对于100%的数据 100000≥n≥1
所以我还是交了个DFS,因为当时时间复杂度算错了一位,以为贪心暴力不能
实际上做法就是贪心暴力
只是要判断罢了,就是当这个数又大又可以选的时候,要看看拼完这个数剩下的火柴棍能不能起码凑完剩下的位数,还有剩下的位数能不能放下所有火柴棍。
就没啦!
#include <iostream>
#include <cstdio>
using namespace std;
int t,n,i,j,k,a[10]={6,2,5,5,4,5,6,3,7,6},s,sle[6]={2,4,5,3,7,6};
char c[1000001];
int main()
{
freopen("match.in","r",stdin);
freopen("match.out","w",stdout);
scanf("%d",&t);
for (i=1;i<=t;i++)
{
scanf("%d%c",&n,&c[0]);
for (j=1;j<=n;j++)
{
scanf("%c",&c[j]);
s+=a[c[j]-48];
}
if (n!=1)
{
for (j=1;j<=n;j++)
for (k=5;k>=0;k--)
if ((n-j)*2<=s-sle[k]&&s-sle[k]>=0&&j!=n&&s-sle[k]<=(n-j)*7||j==n&&s-sle[k]==0)
{
s-=sle[k];
if (k==5)
printf("9");
else
if (k==4)
printf("8");
else
if (k==3)
printf("7");
else
if (k==2)
printf("5");
else
if (k==1)
printf("4");
else
printf("1");
break;
}
}
else
if (a[c[1]-48]==6)
printf("9");
else
if (a[c[1]-48]==5)
printf("5");
else
printf("%c",c[1]);
printf("\n");
}
}
第三题
给定一个区间[1..n],x是区间中的一个数(任意整数),要保证在m次提问(什么什么能整除x吗?)中必定找出x,求m最少为多少?
这题真的水,我是第一个AC的
说着旁边的zzy跑过来要关我机子(来啊,放纵啊)
这题的思路是我莫名其妙推出来的
就是将1~n中所有素数筛出来,然后素数的幂次方最大能到达多少(幂次方在n以内),每个素数的最大指数之和即为m
#include <iostream>
#include <cstdio>
using namespace std;
int n,i,k,s,o;
long long a[100001];
bool b[100001];
void prime(int n)
{
int i,cn;
b[1]=true;
for (i=2;i<=n;i++)
{
if (b[i]) continue;
cn=i*2;
while (cn<=n)
{
b[cn]=true;
cn+=i;
}
}
}
int main()
{
freopen("game.in","r",stdin) ;
freopen("game.out","w",stdout) ;
scanf("%d",&n);
prime(n);
for (i=1;i<=n;i++)
if (!b[i])
{
k++;
a[k]=i;
}
s=k;
k=0;
for (i=1;i<=s;i++)
{
o=a[i];
while (1)
{
k++;
a[i]*=o;
if (a[i]>n) break;
}
}
printf("%d",k);
}
第四题
第n个人是BOSS级的存在,因此不能黑,实际上就是n-1…..气势瘆人
主要是DP思路
DP数组f[i][j]代表选择了i个人混到了j分的方案数
当j在要求的区间l..r内时,就把这个方案数累加
差不多就这样了,然后还有因为有起始分数,所以l要变为l-c,r要变为r-c
然而一次最高只能混到n-1的分数,所以r-c>n-1时,r=n-1
哦,还有因为数据问题,n会非常大(100000),因此数组要滚动
#include <iostream>
#include <cstdio>
#include <memory.h>
using namespace std;
int n,c,l,r,i,j,f[2][1000001];
long long s;
int main()
{
freopen("hack.in","r",stdin);
freopen("hack.out","w",stdout);
scanf("%d%d%d%d",&n,&c,&l,&r);
l-=c;r=min(r-c,n-1);
f[0][0]=1;
for (i=1;(i-1)*i/2<=r;i++)
{
for (j=(i-1)*i/2;j<=r;j++)
{
f[i%2][j]=f[i%2][j-i]+f[(i-1)%2][j-i];
f[i%2][j]%=998244353;
if (l<=j&&j<=r) s=(s+f[i%2][j])%998244353;
}
memset(f[(i-1)%2],0,sizeof(f[(i-1)%2]));
}
printf("%d",s);
}
666

被折叠的 条评论
为什么被折叠?



