天梯赛准备——天梯赛L1(总结)

今天打完PTA了,还是太菜了。。。
把以前整理的关于PTA的心得发一下出来吧,希望以后有需要的朋友能够方便一点吧。

L1-035 情人节

字符串比较可以直接用等号,也可以用strcmp函数(==0为相同) 字符比较则也可以用等号

# include <bits/stdc++.h>
using namespace std;

int main()
{
	long long sum=0;
	string m,a,b,n;
	
	cin>>m;
	n=".";
	while(m!=n){
		sum++;
		if(sum==2) a=m;
		if(sum==14) b=m;
		cin>>m;
	}
	
	if(sum>=14) cout<<a<<" and "<<b<<" are inviting you to dinner...";
	else if(sum>=2&&sum<14) cout<<a<<" is the only one for you...";
	else cout<<"Momo... No one is for you ...";
	
	
	return 0;
}
L1-039 古风排版

1.中途变量出错以后进行改变,那么所有位置都要改变
2.’\0’和’ ’的显示是一样的,要注意,补空格的例子
3.数组定义要小心
4. 纠正一下带空格的字符串/字符输入

https://blog.csdn.net/circle2015/article/details/70880072

字符数组
(1)getline()
读入整行数据,使用回车键输入的换行符来确定输入结尾。
调用方法:cin.getline(str, len)//str储存输入行的数组名称,len读取的字符数
(2)cin.get(str,len)
读取一行输入,直至换行符
getline()将换行夫丢弃,get()讲换行符保留在输入序列里

string
(1)getline(cin,str)
scanf、cin碰到回车、空格和tab会自动结束
1)利用格式符“%[]”它的作用为扫描字符集合。Scanf(“%[^c]”,str); 其中“c”是一个具体的字符常量(包括控制字符)。当输入字符串时,字符“c”将被当作当前输入的结束符。利用此格式符就可以由编程者自己指定一个输入结束符。
可以尝试一下的代码

# include <bits/stdc++.h>
using namespace std;

int main()
{
	char* msg==NULL;
	msg=(char*)malloc(100*sizeof(char));
	scnaf("%[]^\n",msg);
	printf("%s",msg);
	
	return 0;
}
#  include <bits/stdc++.h>
using namespace std;

char c[1100][110];
int main()
{
	int n,s=0,d;
	string a;
	
	cin>>n;
	getchar();
	getline(cin,a);
	
/*	
	for(int i=0;i<1100;i++){
		for(int j=0;j<110;j++)
			c[i][j]=' ';
	}
	*/
	if(a.length()%n!=0) d=a.length()/n+1;
	else d=a.length()/n;
	//cout<<d<<" "<<a.length()<<endl;
	for(int i=d-1;i>=0;i--){
		for(int j=0;j<n;j++){
			if(s<a.length())c[j][i]=a[s++];
			else c[j][i]=' ';
			//cout<<i<<" "<<j<<c[i][j]<<endl;
		}
	}
	
//	cout<<s;
	for(int i=0;i<n;i++){
		if(i>0)cout<<endl;
		for(int j=0;j<d;j++){
			cout<<c[i][j];
		}
	//	cout<<endl;
	}
	return 0;
}
L1-043 阅览室

1.要注意几个坑点,如果同一本书在还没还书记录时有多次被借记录,取最后一次记录为准。
2.一本书在只借一次的情况下有多次还书记录,取最前面的一次还书记录,其余都是无效操作。
3.一本书也有可能被借还借还很多次。
4.用一个标记数组,借了标记为1,只有还的时候有借的记录才能计算,并且还要把标记数组释放。

# include <bits/stdc++.h>
using namespace std;

int main()
{
	int n,sh,b,bhh[1010],bmm[1010],e,ehh[1010],emm[1010];
	char jz[1010];
	int f[1010];
	long long r=0;
	double sum=0;
	
	cin>>n;
	
	memset(bhh,0,sizeof(bhh));
	memset(bmm,0,sizeof(bmm));
	memset(f,0,sizeof(f));
	for(int i=0;i<n;i++){
		cin>>sh;
		while(sh!=0){
			cin>>jz[sh];
			if(jz[sh]=='S'){
				cin>>bhh[sh];
				getchar();
				cin>>bmm[sh];
				f[sh]=1;
			}
			if(jz[sh]=='E'){
				cin>>ehh[sh];
				getchar();
				cin>>emm[sh];
				if(f[sh]==1){
					b=bhh[sh]*60+bmm[sh];
					e=ehh[sh]*60+emm[sh];
					//cout<<e-b<<endl;
					sum+=e-b;
					r++;
					f[sh]=0;
				}
			}
			//cout<<" "<<sh<<" "<<jz[sh]<<" "<<bhh[sh]<<":"<<bmm[sh]<<endl;
			cin>>sh;
			b=0,e=0;
		}
		
		if(sh==0){
			cin>>jz[sh];
			if(jz[sh]=='S'){
				cin>>bhh[sh];
				getchar();
				cin>>bmm[sh];
			}
			if(jz[sh]=='E'){
				cin>>bhh[sh];
				getchar();
				cin>>bmm[sh];
			}
			if(r==0)cout<<0<<" "<<0<<endl; 
			else printf("%lld %.0lf\n",r,sum/r);
		}
		
		sum=0,r=0;
		memset(f,0,sizeof(f));
	}
	
	return 0;
}
L1-049 天梯赛座位分配

1.哪个要最近改变,哪个放在循环的最里面,依次向外。
2.实现非等差循环的原理
3.注意找到循环的规律,就是具体是怎么跳的

# include <bits/stdc++.h>
using namespace std;


int main()
{
	int n,maxx=0,sum=0,d=-1;
	int sn[110];
	int b[110][10][10];
	
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>sn[i];
		if(sn[i]>maxx)maxx=sn[i];
	}
	
	for(int i=0;i<maxx;i++){//第几队 
		for(int j=0;j<10;j++){//每队10个人 
			for(int k=0;k<n;k++){//n个学校 
				if(sn[k]<=i){//实现非等差循环 
					continue;
				}
				if(d==k){
					sum+=2;
				} else{
					sum++;
				}
				d=k;
				b[k][i][j]=sum;
			}
		}
	}
	
	for(int i=0;i<n;i++){
		cout<<"#"<<i+1<<endl;
		for(int j=0;j<sn[i];j++){
			for(int k=0;k<9;k++){
				cout<<b[i][j][k]<<" ";
			}
			cout<<b[i][j][9]<<endl;
		}
	}
	return 0;
}
L1-050 倒数第N个字符串

一开始找规律的时候不能错,关于位数的问题一定要小心,不然debug会极其恶心

# include <bits/stdc++.h>
using namespace std;

int main()
{
	long long d;
	int l,n;
	int w[7];
	char z[27]={' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
	
	memset(w,0,sizeof(w));
	cin>>l>>n;
	n=pow(26,l)-n;
	/*
	cout<<n<<endl;
	cout<<n/(26*26)<<endl;
	cout<<n%(26*26)/26<<endl;
	cout<<n%26<<endl;
	*/
	
	for(int i=l;i>=1;i--){
		d=pow(26,i-1);
		w[i]=n/d;
		/*if(w[i]==0){
			w[i]=1;
			w[i+1]--;
		}*/
		n=n%d;
		cout<<z[w[i]+1];
	}
	
	
	return 0;
}
L1-054 福到了

正解:

# include <bits/stdc++.h>
using namespace std;

int main()
{
	char a;
	int n,flag=0;
	char y[110][110];
	char h[110][110];
	
	cin>>a;
	cin>>n;
	
	getchar();
	
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			y[i][j]=getchar();
		}
		getchar();
	}
	for(int i=n-1;i>=0;i--){
		for(int j=n-1;j>=0;j--){
			h[n-1-i][n-1-j]=y[i][j];
		}
	}
	
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(h[i][j]!=y[i][j]){
				flag=1;
				break;
			}
		}
	}
	
	if(flag){
	}else{
		cout<<"bu yong dao le"<<endl;
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(h[i][j]==' ') cout<<h[i][j];
			else cout<<a;
		}
		cout<<endl;
	}
	
	return 0;
}

错解:

# include <bits/stdc++.h>
using namespace std;

int main()
{
	char a;
	int n,flag=0;
	string y[110];
	string h[110];
	
	cin>>a;
	cin>>n;
	
	getchar();
	
	for(int i=0;i<n;i++){
		//cout<<i<<endl;
		getline(cin,y[i]);
		//getchar();
	}
	for(int i=n-1;i>=0;i--){
		for(int j=n-1;j>=0;j--){
			h[n-1-i][n-1-j]=y[i][j];
		}
	}
	
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(h[i][j]!=y[i][j]){
				flag=1;
				break;
			}
		}
	}
	
	if(flag){
	}else{
		cout<<"bu yong dao le"<<endl;
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(h[i][j]==' ') 
			  	cout<<h[i][j];
			else 
				cout<<a;
		}
		cout<<endl;
	}
	
	return 0;
}


第二个会出现段错误,为什么?
关于为什么会出现段错误:string本身的长度并不是确定的,如果他给的长度是99,那么你访问到了100,就会造成数组越界,就出现了段错误。

# include <bits/stdc++.h>
using namespace std;

int main()
{
	char a;
	int n,flag=0;
	string y[200];
	string h[200];
	
	for(int i=0;i<200;i++){
		for(int j=0;j<200;j++){
		//所以要对string 这一行进行初始化
		//也就是要确定接下来要调用的空间
			y[i]+=' ';
			h[i]+=' ';
		}
	}
	
	cin>>a;
	cin>>n;
	
	getchar();
	
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			y[i][j] = (char)getchar();	
		}
		
		getchar();
	}
	for(int i=n-1;i>=0;i--){

		for(int j=n-1;j>=0;j--){
			h[n-1-i][n-1-j]=y[i][j];
		}
	}
	
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(h[i][j]!=y[i][j]){
				flag=1;
				break;
			}
		}
	}
	
	if(flag){
	}else{
		cout<<"bu yong dao le"<<endl;
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(h[i][j]==' ') 
			  	cout<<h[i][j];
			else 
				cout<<a;
		}
		cout<<endl;
	}
	
	return 0;
}

L1-055 谁是赢家

规则为:如果一位艺人的观众票数高,且得到至少 1 名评委的认可,该艺人就胜出;或艺人的观众票数低,但得到全部评委的认可,也可以胜出。节目保证投票的观众人数为奇数,所以不存在平票的情况。本题就请你用程序判断谁是赢家。

正解:

# include <bits/stdc++.h>
using namespace std;

int main()
{
	int pa,pb,a=0,b=0,c;
	
	cin>>pa>>pb;
	
	for(int i=0;i<3;i++){
		cin>>c;
		if(c==1) b++;
		else a++;
	}
	
	if(a==3){
		cout<<"The winner is a: "<<pa<<" + "<<a;
	}else if(b==3){
		cout<<"The winner is b: "<<pb<<" + "<<b;
	}else{
		if(pa>pb&&a!=0) cout<<"The winner is a: "<<pa<<" + "<<a;
		else if(pb>pa&&b!=0) cout<<"The winner is b: "<<pb<<" + "<<b;
	}
	
	return 0;
}

错解:

# include <bits/stdc++.h>
using namespace std;

int main()
{
	int pa,pb,a=0,b=0,c;
	
	cin>>pa>>pb;
	
	for(int i=0;i<3;i++){
		cin>>c;
		if(c==1) b++;
		else a++;
	}
	
	if(pa>pb){
		if(a!=0){
			cout<<"The winner is a: "<<pa<<" + "<<a;
		}
	}else{
		if(b==3){
			cout<<"The winner is b: "<<pb<<" + "<<b;
		}
	}
	
	return 0;
}

第二个代码是错误的,比一定是pb<pa&&b=3的情况,还有可能是pb>pa&&b=3的情况,所以这题的关键是找到a=3\b=3这两个点
这题选手获胜的关键是是否有三个评委的支持,如果他有三个评委的支持则坑定获胜,如果他没有1<= <个的选手的支持则要比较观众票数谁多了。

L1-048 矩阵A乘以B

关于Presentation Error
首先可以肯定的是,思路没有错,输出结果也与标准输出结果非! 常!接!近!出现这个错误最可能的原因是,在输出结果的后面,多了或少了没什么意义的空格,tab,换行符等等。所以,请先认真检查程序的输出结果是否与标准完!全!一!致!OJ平台对格式的检查可以说是非!常!严!格!
如果认真检查过,真的没有问题的话,唯一的可能,就是标准输出结果存在问题!标准的输出结果后面有些你看不见的空格或者换行符!加个空格或换行符再试一试!

# include <bits/stdc++.h>
using namespace std;

int a[1000][1000],b[1000][1000],c[1000][1000];
int main()
{
	int ra,ca,rb,cb;
	
	memset(c,0,sizeof(c));
	cin>>ra>>ca;
	getchar();
	for(int i=0;i<ra;i++){
		for(int j=0;j<ca;j++){
			cin>>a[i][j];
			//getchar();
		}
	}
	
	cin>>rb>>cb;
	getchar();
	for(int i=0;i<rb;i++){
		for(int j=0;j<cb;j++){
			cin>>b[i][j];
			//getchar();
		}
	}
	
	if(ca!=rb) cout<<"Error: "<<ca<<" != "<<rb;
	else{
		cout<<ra<<" "<<cb<<endl;
		for(int i=0;i<ra;i++){
			if(i!=0)cout<<endl;
			for(int j=0;j<cb;j++){
				if(j!=0)cout<<" ";
				for(int k=0;k<ca;k++){
					c[i][j]+=a[i][k]*b[k][j];
				}
				cout<<c[i][j];
			}
		}
	}
	
	return 0;
}
L1-046 整除光棍

模拟除法(NB呀,不仅好理解,而且代码短,极其好写)

# include <bits/stdc++.h>
using namespace std;

int main()
{
	int x,sum=0,y,flag=1,n=0;
	
	cin>>x;
	while(sum<x){
		sum=sum*10+1;
		n++;
	}
	while(flag){
		y=sum%x;
		if(y==0) flag=0;
		else n++;
		cout<<sum/x;
		sum=sum%x*10+1;
	}
	cout<<" "<<n;
	return 0;
}

就是先把被除数加到比除数大,然后进行除法,如果余数为0则证明结束了(因为题目说题目输入的奇数是可以被光棍数整除的),否则则在余数右边加上1
如何判断一个数是否为整数:int(a)==a;

L1-033 出生年

如何判断以一个数有几个数不相同:
搞一个标记数组 int f[10] memset(f,0,sizeof(f));
将该数的每位相应的f[i]++;
最后遍历该标记数组,如果该表标记数组不为0则sum++

# include <bits/stdc++.h>
using namespace std;

int w[4],f[10],a=0;
int y,n,x=0,flag=1,s=0;
void cl(int a)
{
	for(int i=3;i>=0;i--){
		w[i]=a%10;
		f[w[i]]++;
		a=a/10; 
	}
	return ;
}
int main()
{
	memset(w,0,sizeof(w));
	memset(f,0,sizeof(f));
	cin>>y>>n;
	while(flag){
		cl(y);
		for(int i=0;i<10;i++){
			if(f[i]!=0){
				s++;
				//cout<<i<<endl;
			}
		}
		
		//cout<<" "<<s<<endl;
		if(s==n){
			//cout<<a<<endl;
			cout<<x<<" ";
			for(int i=0;i<4;i++){
				cout<<w[i];
			}
			flag=0;
		}
		else{
			x++;
			y++;
			s=0;
			memset(w,0,sizeof(w));
			memset(f,0,sizeof(f));
		}
		//a++;
	}

	return 0;
}
L1-019 谁先倒

关于逻辑的问题
则一定要把限制条件写完整了,否则容易wa。还有就是,题目里面一定有比较隐蔽的条件,而这个条件一般就是该题目的考察点,一定要不易否则分数一定比较低。
关于喝酒的限制条件:
这条规则有点隐秘,但是不发现就只有个位数的分数:

两人同赢或两人同输则继续下一轮

这代表打了平局=没有输家=没人要饮酒

不是说两个人都喝酒相当于都没喝,
极端一点,两个人一杯酒都不能喝,但如果第一局平局(都划出了那个数字),两个都超过极限,你说谁先倒下?

就是一定要有人输的时候再输家喝酒而不是输的人喝酒。所以,一定要是一个人的划的数字等于两个人喊的数字而另一个人不等于。

关于输出:
一定要喝的杯数大于酒量才能输出。

输出的条件是有一个人和的杯数大于酒量,也就是说if(aa>a||bb>b)才行,这个条件一定要写,不然第二个样例会wa

# include <bits/stdc++.h>
using namespace std;

int main()
{
	int a,b,n,aa=0,bb=0,sum=0;
	int aj[110],ah[110],bj[110],bh[110];
	
	cin>>a>>b;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>aj[i]>>ah[i]>>bj[i]>>bh[i];
		sum=aj[i]+bj[i];
		if(sum==ah[i]&&sum!=bh[i]){
			aa++;
		}
		if(sum==bh[i]&&sum!=ah[i]){
			bb++;
		}
		if(aa>a||bb>b){
			if(aa>a){
				cout<<"A"<<endl;
				cout<<bb;
				break;
			}	
			if(bb>b){
				cout<<"B"<<endl;
				cout<<aa;
				break;
			}
		}	
	}
	return 0;
 } 
L1-017 到底有多二

string n;
n[n.length()-1]才是指最后一位

# include <bits/stdc++.h>
using namespace std;

int main()
{
	string n;
	double e,a=1,b=1,len=0,c=0;
	
	cin>>n;
	
	len=n.length();
	
	//cout<<n[n.length()-1]<<endl;
	if(n[0]=='-'){
		a+=0.5;
		len--;
	}
	if((n[n.length()-1]-'0')%2==0){
		b+=1;
	}
	
	for(int i=0;i<n.length();i++){
		if(n[i]=='2')c++;
	} 
	
	e=c/len*a*b*100.0;
	
	printf("%.2f",e);
	cout<<"%";
	return 0;
}
L1-020 帅到没朋友

数字转字符串

string change(int a)
{
	string c;
	stringstream c;
	sss<<a;
	ss>>c;
	return c;
}

字符串转数字

int change(string a)
{
	string stream ss;
	int c;
	ss<<a;
	ss>>c;
	return c;
}

https://zhidao.baidu.com/question/576359612.html

# include <bits/stdc++.h>
using namespace std;

int change(string a)
{
	stringstream ss;
	int c;
	ss<<a;
	ss>>c;
	return c;
}
int main()
{
	int n,k,f[100100],u[100100],m,sum=0,flag=0;
	string a,b;
	
	memset(f,0,sizeof(f));
	memset(u,0,sizeof(u));
		
	cin>>n;
	getchar();
	for(int i=0;i<n;i++){
		cin>>k;
		getchar();
		for(int j=0;j<k;j++){
			cin>>a;
			getchar();
			if(k!=1){
				f[change(a)]=1;
			}/*else{
				f[change(a)]=0;
			}*///有可能前面在k!=0出现过一次又被覆盖了,
			//不要随意等于初始化的值,尽可能写赋值不一样的 
		}
	}
	
	
	cin>>m;
	getchar(); 
	for(int i=0;i<m;i++){
		cin>>b;
		if(f[change(b)]==0&&u[change(b)]==0){
			sum++;
			if(flag) cout<<" ";
			cout<<b;
			u[change(b)]=1;
			flag=1;
		}
		getchar();
	}
	
	if(sum==0){
		cout<<"No one is handsome";
	}
	return 0;
}
L1-006 连续因子

1.要get到一个点就是,这个因子是连续的,so你只要知道起始和长度就可以了
2还要注意到一个点就是素数还要注意到
3.最后就是,如果n%i之后就再也没有了,那么就要直接标记了

# include <bits/stdc++.h>
using namespace std;

bool prime(int a)
{
	for(int i=2;i<=sqrt(a);i++){
		if(a%i==0) return false;
	}
	return true;
}
int main()
{
	int n,d=0,maxx=0,start=0,startmaxx=0,nn;
	
	cin>>n;
	if(prime(n)){
		cout<<1<<endl;
		cout<<n;
		return 0;
	}
	
	nn=n;
	for(int i=2;i<=n/2;i++){
		if(nn%i==0){
			d++;
			start=i;
			nn=nn/i;
			if(d>maxx){
				maxx=d;
				//d=0;
				startmaxx=start;
			}
		//	cout<<nn<<endl;
		}else{
			continue;
		}
		for(int j=(i+1);j<=n/2;j++){
			if(nn%j==0){
				d++;
				nn=nn/j;
				if(d>maxx){
					maxx=d;
					//d=0;
					startmaxx=start;
				}
			//	cout<<nn<<endl;
			}else{
				break;
			}
			
		}
		nn=n;
		d=0;
	}

	cout<<maxx<<endl;
	for(int i=startmaxx;i<(startmaxx+maxx);i++){
		if(i!=startmaxx) cout<<"*";
		cout<<i;
	}
	return 0;
}
L1-009 N个数求和

模拟先第一项和第二项分母同分,分子加,同余,然后将其放在第二项,然后第二项和第三项操作。

# include <bits/stdc++.h>
using namespace std;

typedef long long LL;
LL fz,fm,zs,a,b,t;
LL gcd(LL a,LL b)
{
	return b==0?a:gcd(b,a%b);
}
int main()
{
	int n;
	
	cin>>n;
	if(n==0){
		cout<<"0";
		return 0;
	}
	
	cin>>fz;
	getchar();
	cin>>fm;
	
	for(int i=1;i<n;i++){
		cin>>a;
		getchar();
		cin>>b;
		a*=fm;
		fz*=b;
		fm*=b;
		fz+=a;
		t=gcd(fz,fm);
		fz/=t;
		fm/=t;
	}
	
	//cout<<"@";
	
	t=gcd(fz,fm);
	fz/=t;
	fm/=t;
	
	if(fz==0){
		cout<<"0";
		return 0;
	}
	if(fm<0){
		fz=fz*(-1);
		fm=fm*(-1);
	}
	
	zs=fz/fm;
	fz=fz%fm;
	
	if(zs!=0){
		cout<<zs;
	}
	if(fz&&zs){
		cout<<" ";
	}
	if(fz!=0){
		cout<<fz<<"/"<<fm;
	}
	
	return 0;
 } 


愉快结束小尾巴~~
个人建议如果也是刚入门的朋友的话,可以刷一下PTA天梯赛的L1和zzuoj的寒假马拉松啊,会有一些巩固于提升的。
ps:链接:https://pintia.cn/
http://222.22.65.164/problemset.php?search=2019寒假马拉松

本人菜鸡一个,关于算法还在学习,所以blog中的内容大部分是总结各位大佬的,如果有侵权要求删除或者出处注明不全的,非常抱歉,欢迎站内私信啊。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值