洛谷刷题笔记
目录
P4414 [COCI2006-2007#2] ABC
【入门1】顺序结构 - 题单 - 洛谷 完成✔
P5705 【深基2.例7】数字反转
大佬的题解:登录 - 洛谷
#include <cstdio> using namespace std; char a, b, c, d; int main(){ scanf("%c%c%c.%c", &a, &b, &c, &d); printf("%c.%c%c%c", d, c, b, a); return 0; }
#include<bits/stdc++.h>//万能头文件 using namespace std; string a; signed main() { cin>>a; int len=a.size();读取长度 for(int i=len-1;i>=0;i--)反转 cout<<a[i]; return 0; }
#include <cstdio> #include <cstring> using namespace std; char c[17]; int main() { scanf("%s", c); for(int i = strlen(c) - 1; i >= 0; --i) printf("%c", c[i]); return 0; }
#include<bits/stdc++.h> //文件头 using namespace std; string a; //定义字符串 int main() { cin>>a; //输入 reverse(a.begin(),a.end()); //反转 cout<<a; //输出 return 0; //养成好习惯 }
#include<bits/stdc++.h> using namespace std; int z,x,dz; int main(){ scanf("%d.%d",&z,&x); //输入整数部分+小数点+小数部分 while(z){ //愉快的反转环节 dz=dz*10+z%10; z/=10; } printf("%d.%d\n",x,dz); //就可以输出了 return 0; }
最开始自己思考的时候思路在用取余的方法获取每一位数然后想办法给它们换位置,非常繁琐复杂。。。
P5707 【深基2.例12】上学迟到
大佬的题解:登录 - 洛谷
#include<bits/stdc++.h> using namespace std; double s,v,m; int n,a,t,b; int main() { cin>>s>>v; n=8*60+24*60;//两天总共的分钟数 t=ceil(s/v)+10;//ceil()很重要,向上取整,否则按C++逻辑会向下取整导致行走时间少。 n=n-t;//得出剩下的时间。 if(n>=24*60) n-=24*60;//判断是否在前一天。 b=n%60;//得出出发分。 a=n/60;//得出出发时 printf("%02d:%02d",a,b); /* if(a<10)//慢慢判断是否补0 { if(b<10) cout<<"0"<<a<<":0"<<b; else cout<<"0"<<a<<":"<<b; } else { if(b<10) cout<<a<<":0"<<b; else cout<<a<<":"<<b; } */ return 0; }
看别人的题解时找到了更简便解决的补零问题的方法:printf("%02d:%02d", a, b);
【入门2】分支结构 完成✔
P5710 【深基3.例2】数的性质
大佬的题解:
#include<iostream> using namespace std; int main() { int n; bool a=0,b=0,c=0,d=0; cin>>n; if(n%2==0&&(n>4&&n<=12))a=1; //必须要符合两个条件 if(n%2==0||(n>4&&n<=12))b=1; //至少要符合一个条件 if(n%2==0^(n>4&&n<=12))c=1; //必须要只符合一个条件 if(n%2!=0&&(n<=4||n>12))d=1; //必须要两个条件全都不符合 cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl; //输出 return 0; }
自己打的时候一直在第三个判断条件纠结,直到看到别人的题解时候才想起被我忽略掉的异或^,也知道了其他条件判断更简洁的代码。
第三个 if 中的 ^ 定义为:1 ^ 1 = 0
0 ^ 0 = 0
1 ^ 0 = 1
0 ^ 1 = 1史上最通俗易懂的异或运算详解【含例题及应用】_来老铁干了这碗代码的博客-CSDN博客
大佬的题解: (这个思路妙啊)#include<bits/stdc++.h> using namespace std; int main() { short a=0,b=0,c=0,d=0,k=0; long long n; cin>>n; k+=(n%2==0); k+=(4<n&&n<=12); if(k==2)a=1; if(k>0)b=1; if(k==1)c=1; if(k==0)d=1; cout<<a<<' '<<b<<' '<<c<<' '<<d<<endl; return 0; }
if 也可以使用 switch 来代替
P1085 [NOIP2004 普及组] 不高兴的津津
我的题解:
#include<bits/stdc++.h> using namespace std; int main() { int a, b, c, d, e, f, g, h, i, j, k, l, m, n; cin >> a >> b >> c >> d >> e >> f >> g >> h >> i >> j >> k >> l >> m >> n; int arr1[7] = { a + b,c + d, e + f, g + h, i + j, k + l, m + n }; int arr2[7] = { a + b,c + d, e + f, g + h, i + j, k + l, m + n }; int len = sizeof(arr1) / sizeof(arr1[0]); int temp; for (int i = 0; i < len - 1; i++) { for (int j = 0; j < len - i - 1; j++) { if (arr1[j + 1] < arr1[j]) { temp = arr1[j + 1]; arr1[j + 1] = arr1[j]; arr1[j] = temp; } } } if (arr1[len - 1] > 8) { for (int p = 0; p < len; p++) { if (arr2[p] == arr1[len - 1]) { cout << p + 1 << endl; break; } } } else { cout << 0<<endl; } }
自己打的时候想的是用冒泡排序之后还要解决星期几和“如果有两天或两天以上不高兴的程度相当,则输出时间最靠前的一天。”的问题(所以用了2个数组),思路不够精简。
大佬的题解:
#include<iostream> #include<cstdio> #include<cstdlib> using namespace std; //作为新手的我会的都写上 int main () { int a,b,s,max=0,i,day=0; //a,b是我们津津(以下简称JJ)每天上课时间,s意为sum是上课时间之和 for (i=1;i<8;i++) // i为循环变量,day是JJ一周最不高兴的一天 { cin>>a>>b; //输入a,b s=a+b; //计算一天的上课时间 if ((s>max)&&(s>8)) max=s,day=i; //在超过8小时且比之前几天都大的s时,将s赋给最大值,并记录下JJ的这天 } cout<<day; //由于day初值是0,所以如果JJ一周都开心就输出0 return 0; }
用if ((s>max)&&(s>8)) max=s,day=i; 就可以解决输出星期几和“如果有两天或两天以上不高兴的程度相当,则输出时间最靠前的一天。”的问题,也同时解决了找出哪一天上课时间最长和一周是否都开心的问题。
P1909 [NOIP2016 普及组] 买铅笔
我自己的题解太萌新了,这里记录一下看到的2个我不太好理解的大佬的题解登录 - 洛谷:
#include<bits/stdc++.h> using namespace std; long n,a1,a2,b1,b2,c1,c2,pen1,pen2,pen3,x[3]; int compare(int a1,int a2,int b1,int b2,int c1,int c2) { while(pen1<n) { pen1+=a1; x[0]+=a2; } while(pen2<n) { pen2+=b1; x[1]+=b2; } while(pen3<n) { pen3+=c1; x[2]+=c2; } return x[0],x[1],x[2]; } int main() { cin>>n>>a1>>a2>>b1>>b2>>c1>>c2; compare(a1,a2,b1,b2,c1,c2); sort(x,x+3); cout<<x[0]; return 0; }
解释一下,a1为第一种包装的价格,a2为第一种包装的价格。 那么b,c就如下了。
X【0】,X【1】,X【2】分别记录答案的值,再sort一遍输出最小值。
#include<cstdio> using namespace std; int i,j,k,n,m,w,ans; int main(){ scanf("%d",&n); for(i=0;i<3;i++){ scanf("%d%d",&j,&k);m=j;w=k;//输入并存下初始的价格与数量 while(j<n){j<<=1;k<<=1;}//价格与数量不断*2直到数量大于n while(j>n){j-=m;k-=w;}//*2有可能导致买太多了,减去一些 while(j<n){j+=m;k+=w;}//减去之后又可能太少了,加上一些 //其实就是大幅度地上调,然后做一些微调 if(k<ans||ans==0)ans=k;//判断是否是最小花费 } printf("%d\n",ans); return 0;//输出并返回 }
大佬原话:
P5717【深基3.习8】三角形分类
一开始自己83分的题解:
#include<bits/stdc++.h> using namespace std; int main() { int a, b, c; cin >> a >> b >> c; if (a + b > c && a + c > b && b + c > a) { if ((a*a + b * b == c * c) || (b * b + c * c == a * a) || (a * a + c * c == b * b)) { cout << "Right triangle" << endl; } else if ((a * a + b * b > c * c) ||( b * b + c * c > a * a) ||( a * a + c * c > b * b)) { cout << "Acute triangle" << endl; } else if ((a * a + b * b < c * c) || (b * b + c * c < a * a) || (a * a + c * c < b * b)) { cout << "Obtuse triangle" << endl; } if(a==b||a == c||b == c ) { cout << "Isosceles triangle" << endl; } if (a==b&&b==c) { cout << "Equilateral triangle" << endl; } } else { cout << "Not triangle" << endl; } }
看了题解后知道:
- 两条较短边的平方和大于最长边的平方,此三角形就是锐角三角形;
- 两条较短边的平方和小于最长边的平方,此三角形就是钝角三角形;
- 两条边短边的平方和等于最长边的平方,此三角形就是直角三角形。
即要对3条边进行从小到大排序;
大佬题解:
#include<bits/stdc++.h> using namespace std; int a[4],n=3; int main() { for(int i=1; i<=3; ++i) scanf("%d",&a[i]); sort(a+1,a+n+1); if(a[1]+a[2]<=a[3]) { printf("Not triangle\n"); return 0; } if(a[3]*a[3]==(a[2]*a[2]+a[1]*a[1])) printf("Right triangle\n"); else if(a[3]*a[3]>(a[2]*a[2]+a[1]*a[1])) printf("Obtuse triangle\n"); else if(a[3]*a[3]<(a[2]*a[2]+a[1]*a[1]))printf("Acute triangle\n"); if(a[1]==a[2]||a[2]==a[3]||a[3]==a[1]) printf("Isosceles triangle\n"); if(a[1]==a[2]&&a[2]==a[3]) printf("Equilateral triangle\n"); return 0; }
注意sort函数的用法!!!、、、
P1888 三角函数
这题重点在与求最大公约数
- __gcd(x,y) 但是在VS用会报错、、、(那就自己定义↓)
- 辗转相除法:
int __gcd(int x, int y) { int temp; while (x % y != 0) { temp = x % y; x = y; y = temp; } return y; }
用较大的数除以较小的数,再以除数和余数反复做除法运算,当余数为0时,取当前算式除数为最大公约数。如果用小数除以大数,只是过程多了一步,结果没有差别,所以写代码时不用考虑两个数的大小。
P4414 [COCI2006-2007#2] ABC
最后一步根据输入的ABC顺序来输出不同大小的3个数有2种方法:
#include<iostream> #include<algorithm> using namespace std; int a[3]; char A,B,C; int main() { cin>>a[0]>>a[1]>>a[2]; cin>>A>>B>>C; sort(a,a+3);//懒懒_(:з」∠)_排序法 cout<<a[A-'A']<<" "<<a[B-'A']<<" "<<a[C-'A'];//字母是大写,减去‘A’后得到0(A),1(B),2(C)。 return 0; }
第一种:cout<<a[A-'A']<<" "<<a[B-'A']<<" "<<a[C-'A'];//字母是大写,减去‘A’后得到0(A),1(B),2(C)。
#include<iostream> using namespace std; int a,b,c,i,x,y,z,sum; char ch; int main() { cin>>x>>y>>z; sum=x+y+z; a=min(min(x,y),z); c=max(max(x,y),z); b=sum-a-c; for(i=1;i<=3;i++) { cin>>ch; if(ch=='A') cout<<a<<' '; if(ch=='B') cout<<b<<' '; if(ch=='C') cout<<c<<' '; } return 0; }
第二种:
for(i=1;i<=3;i++)
{
cin>>ch;
if(ch=='A') cout<<a<<' ';
if(ch=='B') cout<<b<<' ';
if(ch=='C') cout<<c<<' ';
}即用if条件判断。
P1055 [NOIP2008 普及组] ISBN 号码
一直纠结于int和char类型转换的问题,直到后面看到大佬写的一个和我思路一样的题解:
#include<cstdio> using namespace std; int sbm;//mod11的余数 char s[11],ch;//ISBN码和识别码 int main() { scanf("%c-%c%c%c-%c%c%c%c%c-%c",&s[1],&s[2],&s[3],&s[4],&s[5],&s[6],&s[7],&s[8],&s[9],&s[10]); sbm=((s[1]-48)*1+(s[2]-48)*2+(s[3]-48)*3+(s[4]-48)*4+(s[5]-48)*5+(s[6]-48)*6+(s[7]-48)*7+(s[8]-48)*8+(s[9]-48)*9)%11; if (sbm<10) ch=sbm+48;//计算识别码 else ch='X'; if (ch==s[10]) printf("Right"); //判断识别码是否正确 else printf("%c-%c%c%c-%c%c%c%c%c-%c",s[1],s[2],s[3],s[4],s[5],s[6],s[7],s[8],s[9],ch); return 0; }
大概理解是 由字符型转为int型的方法是 '1'-'0'=1或者'1'-48=1