天梯赛准备——天梯赛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%E5%AF%92%E5%81%87%E9%A9%AC%E6%8B%89%E6%9D%BE
本人菜鸡一个,关于算法还在学习,所以blog中的内容大部分是总结各位大佬的,如果有侵权要求删除或者出处注明不全的,非常抱歉,欢迎站内私信啊。。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】