9月11日队内赛XJOI总结

今天教练组织了一次难度与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 2N 行。
其中第一行是二个整数 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,大佬认为题目简单请勿喷蒟蒻。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值