今天教练组织了一次难度与CSP普及组超不多难度的队内赛,题目难度比较水,但事实证明我到底有多菜,四道题,满分390,结果我就考了
155
155
155 分,队内
3
3
3 个人,我倒一,有
100
100
100 分是因为最水题多测不清空,惨遭爆
0
0
0,还有40分是因为判断数是否被三整除写错了运算符导致丢失,刚看到成绩简直气死,说到底还是自己太粗心,明明算法没错可就是少分,整个人都不好了。下次队内赛一定要仔细认真,马上就要打我人生第一场CSP了,还有一个月一定要好好刷题,虽然这次考砸了,但等到CSP一定要考好。
以下是题面:
一、倍数
描述:Y 老师是个小学生,他连 20 以内的倍数问题都不会写,要你们帮他写个程序完成数学作业。
输入:
第一行一个整数
N
N
N,表示有
N
N
N 组数据。
接下来有
2
∗
N
2*N
2∗N 行。
其中第一行是二个整数
S
S
S,作为被除数,和
m
m
m。
其中第二行是
m
m
m 个整数
B
B
B,作为除数
输出:
每组数据对应一行输出:
Y
e
s
Yes
Yes 表示
S
S
S 是
B
B
B 的倍数。
N
o
No
No 表示
S
S
S 不是
B
B
B 的倍数。
多个除数之间用空格隔开
样例输入:
2
1000 3
5 9 17
2048 3
16 8 10
样例输出:
Yes No No
Yes Yes No
数据范围:
对于20%的数据,B只有一个为2
对于20%的数据,B只有一个为3
对于40%的数据, S的长度<=1e1000
对于所有数据,除数的数量为18个,S的长度<=1e1000000,N<=10;
Y老师慈悲心大发,B只可能是2、3、4、5、6、8、9、10、11、12、14、15、16、18
本蒟蒻的 LJ 思路是将每一个数都作为一种情况去判断,为了不 T 我加了标记,虽然感觉这题用这种方法写会很难调,但我还是毅然决然地写下了以下代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m;
char S[60000000];
int orz[20];
int main() {
freopen("yi.in","r",stdin);
freopen("yi.out","w",stdout);
scanf("%d",&n);
while(n--) {
cin>>S>>m;
int len=strlen(S);
memset(orz,0,sizeof(orz));
while(m--) {
int k;
cin>>k;
if(orz[k]==1) {
printf("Yes ");
continue;
}
if(orz[k]==2) {
printf("No ");
continue;
}
if(k==2) {
if(((S[len-1]-'0')%2)==0 ) {
printf("Yes ");
orz[k]=1;
continue;
} else {
printf("No ");
orz[k]=2; orz[4]=2; orz[6]=2; orz[8]=2; orz[10]=2; orz[12]=2; orz[16]=2; orz[18]=2;
continue;
}
}
if(k==3) {
int ans=0,i=0;
while(i<len) ans==S[i]-'0',i++;
if( ans%3==0 ) {
printf("Yes ");
orz[k]=1;
continue;
} else {
printf("No ");
orz[k]=2;orz[6]=2;orz[9]=2;orz[12]=2;orz[15]=2;orz[18]=2;
continue;
}
}
if(k==4) {
if( ( (S[len-1]-'0'+(S[len-2]-'0')*10) %4 ) == 0 ) {
printf("Yes ");
orz[k]=1;
continue;
} else {
printf("No ");
orz[k]=2; orz[4]=2; orz[8]=2; orz[12]=2; orz[16]=2;
continue;
}
}
if(k==5) {
if(S[len-1]=='0' ||S[len-1]=='5') {
printf("Yes ");
orz[k]==1;
continue;
} else {
printf("No ");
orz[k]=2; orz[10]=2; orz[15]=2;
continue;
}
}
if(k==6) {
int ans=0,i=0;
while(i<len) ans+=S[i]-'0',i++;
if( ( ( (S[len-1]-'0') %2 )==0 )&&( ans%3==0 ) ) {
printf("Yes ");
orz[k]=1;
continue;
} else {
printf("No ");
orz[6]=2; orz[12]=2; orz[18]=2;
continue;
}
}
if(k==8) {
if( ( (S[len-1]-'0'+(S[len-2]-'0')*10+(S[len-3]-'0')*100) %8 ) == 0 ) {
printf("Yes ");
orz[k]=1;
continue;
} else {
printf("No ");
orz[8]=2; orz[16]=2;
continue;
}
}
if(k==9) {
int ans=0,i=0;
while(i<len) ans+=S[i]-'0',i++;
if( ans%9 == 0 ) {
printf("Yes ");
orz[k]=1;
continue;
} else {
printf("No ");
orz[k]=2; orz[18]=2;
continue;
}
}
if(k==10) {
if( S[len-1]=='0' ) {
printf("Yes ");
orz[k]=1;
continue;
} else {
printf("No ");
orz[k]=2;
continue;
}
}
if(k==11) {
long long ansj=0,anso=0,i=0;
while(i<len) {
if(i%2) anso+=S[i]-'0';
else ansj==S[i]-'0';
i++;
}
if( (ansj-anso) %11 == 0 ) {
printf("Yes ");
orz[k]=1;
continue;
} else {
printf("No ");
orz[k]=2;
continue;
}
}
if(k==12) {
int ans=0,i=0;
while(i<len) ans+=S[i]-'0',i++;
if( ( ans % 3 == 0 ) && ( (S[len-1]-'0'+(S[len-2]-'0')*10) %4 ) == 0 ) {
printf("Yes ");
orz[k]=1;
continue;
} else {
printf("No ");
orz[k]=2;
continue;
}
}
if(k==15) {
int ans=0,i=0;
while(i<len) ans+=S[i]-'0',i++;
if(( ans % 3 == 0 ) && ( S[len-1] == '0' || S[len-1] == '5' ) ) {
printf("Yes ");
orz[k]=1;
continue;
} else {
printf("No ");
orz[k]=2;
continue;
}
}
if(k==16) {
if( (S[len-1]-'0'+( S[len-2]-'0' ) * 10 +( S[len-3]-'0' ) * 100 + ( S[len-4] - '0' ) *1000 )%16==0 ) {
printf("Yes ");
orz[k]=1;
continue;
} else {
printf("No ");
orz[k]=2;
continue;
}
}
if(k==18) {
int ans=0,i=0;
while(i<len) ans+=S[i]-'0',i++;
if( ans%9 == 0 && (S[len-1] - '0')%2==0 ) {
printf("Yes ");
orz[k]=1;
continue;
} else {
printf("No ");
orz[k]=2;
continue;
}
}
}
puts("");
}
fclose(stdin);
fclose(stdout);
return 0;
}
期望得分:60分;
实际得分:20分;
感受:测完后发现仔细一看,发现运算符写错了,当场裂开…
收获:写代码不仔细,给分都拿不到。
二、数零
描述:Y老师真是个大水比,连数零都数不清!快,帮忙!
输入:
若干行,每行一个正整数N。
输出:
求N!后面有多少个零
样例输入:
10
样例输出:
2
数据范围:
对于10%的数据,N<=15;
对于30%的数据,N<=40;
对于100%的数据,N<=1000000000。
刚看到这道题觉得太 TM 水了,于是带着对这道题的不屑写下了以下代码:
#include <iostream>
using namespace std;
long long N,sum=0;
int main(){
freopen("er.in","r",stdin);
freopen("er.out","w",stdout);
while(scanf("%lld",&N)!=EOF){
sum=0;//刚开始写的时候没加
while(N){
N/=5;
sum+=N;
}
cout<<sum<<endl;
}
return 0;
}
期望得分:100分;
实际得分:0分;
收获:多测不清空,爆零两行泪…
三、排座位
描述:Y老师被安排当班主任,可是他又菜又爱玩,他安排座位的方法是:全班同学坐成一个圆,要求相邻两个同学的学号和是素数!
输入:
一个正整数N,表示全班同学的人数。
输出:
若干行,每行内容表示符合要求座位顺序的一个排列(1一定放在第一位上)。这些排列按字典序输出。
样例输入:
8
样例输出:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
数据范围:
N<=18
一看,搜索水题, N N N 才18,随便搞。
#include<cmath>
#include<cstring>
#include<string>
#define reg register
#define ri reg int
using namespace std;
bool vis[101],flag=false;
int n,a[101];
template<typename T>inline void read(T &x) {
x=0;
ri f=1;
reg char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-')f=~f+1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
x*=f;
}
inline void write(ri x) {
static int buf[40],top=0;
if(x<0)putchar('-'),x=~x+1;
while(x)buf[++top]=x%10,x/=10;
if(top==0)buf[++top]=0;
while (top) putchar(buf[top--]^48);
putchar(' ');
}
inline bool check(int x) {
for(int k=2; k<=sqrt(x); k++)
if(x%k==0)
return 0;
return 1;
}
inline void print() {
for(int j=1; j<=n; j++)
write(a[j]);
puts("");
flag=true;
}
inline int dfs(int num) {
if(k&1){
for(int i=3; i<=n; i+=2) {
if(check(a[num-1]+i)&&(!vis[i])) {
a[num]=i;
vis[i]=1;
if(num==n) {
if(check(a[n]+a[1]))
print();
} else dfs(num+1);
vis[i]=0;
}
}
}else{
for(int i=2; i<=n; i+=2) {
if(check(a[num-1]+i)&&(!vis[i])) {
a[num]=i;
vis[i]=1;
if(num==n) {
if(check(a[n]+a[1]))
print();
} else dfs(num+1);
vis[i]=0;
}
}
}
}
int main() {
freopen("san.in","r",stdin);
freopen("san.out","w",stdout);
read(n);
a[1]=1;
dfs(2);
if( !flag ) puts("-1\n");
fclose(stdin);
fclose(stdout);
return 0;
}
期望得分:90分(满分90分)
实际得分:85分
感受:
N
=
18
N=18
N=18 T了,发现只有用快读快写,并且加优化才能过。
收获:再也不敢鄙视快读了。
四、又是一个倍数
描述:呵,简单的数学问题怎么可能难道Y老师……以及他的学生?给定一个正整数N和M个十进制数字,请你帮Y老师求出最小N的倍数NN,使得NN中不包含这M个数字中的任意一个!
输入:
第一行两个正整数N和M
第二行M个十进制数字
输出:
一行一个数字NN
样例输入:
2345 3
7 8 9
样例输出:
2345
数据范围:
40%的数据,十进制数字只有2个。
100%的数据,N<=1e4。
一看就是模拟题。
#include<bits/stdc++.h>
#define reg register
using namespace std;
long long n,m;
int a[15];
int main() {
freopen("si.in","r",stdin);
freopen("si.out","w",stdout);
cin>>n>>m;
for(reg int i=1; i<=m; ++i) cin>>a[i];
int i=1;
while(i) {
int k=n*i;
while ( k ) {
int orz=k%10;
for(int i=1; i<=m; ++i) if( orz == a[i] ) goto End;
k/=10;
}
printf("%d",n*i);
return 0;
End:;
i++;
}
puts("-1");
return 0;
}
期望得分:80分;
实际得分:60分;
感受:只有加高精才能过,教练用搜索写的。
收获:永远不要小看数据范围。
总的来说,完全考砸了,心情都被搞差了,但无论如何,一定要细致,不然爆零找谁理论去。
欢迎大佬告诉我这四道题有没有什么好的解决方法,谢谢大佬。
CSDN的第一篇Blog,大佬认为题目简单请勿喷蒟蒻。