2020年5月6号,周三,我开始了我第一次的c++集训刷题,我用了9个多小时做完了所有题目,做完了才发现,原来,C++刷题不是件容易的事。
第一题:进制转换
一开始看到这个题目,感觉很简单,因为这道题的主要算法都学过,思路就是先输入,再按权展开转十进制,最后短除倒取余输出。但真正做起来,并没有那么容易。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n;//进制 4 string a;//数值 5 char r[100000000]; 6 int m;//将要转为的进制 7 int main(){ 8 int p,sum=0,i=0,j=0; 9 cin>>n;//输入 10 cin>>a; 11 cin>>m; 12 p=a.size(); 13 while(p--){//循环,按权展开 14 if(a[p]>'9'){//如果是字母 15 sum+=(a[p]-55)*pow(n,i);//将asll码值-55变成数字,然后在进行幂运算 16 }else{ 17 sum+=(a[p]-'0')*pow(n,i);//如果不是字母, 将asll码值-’0‘的asll码值变成数字,然后在进行幂运算 18 } 19 i++;//将指数+1 20 } 21 while(1){ 22 if(sum%m>9){//如果余数>9,应该用字母 23 r[j]=sum%m+55;//将数值转为字符 24 }else{//否则用数字 25 r[j]=sum%m+'0';//将数值转为字符 26 } 27 if(sum/m==0){//跳出条件:余数为0 28 break; 29 } 30 sum/=m; 31 j++; 32 } 33 int q=strlen(r); 34 while(q--){//倒叙输出 35 cout<<r[q]; 36 } 37 return 0; 38 }
第二题:找筷子
找筷子这道题一开始我想了各种办法解决,但都没能成功,最后我突然想到了一种方法,很适合解这道题。那就是用异或符号“^”,它就可以找出一组数据中落单的数字。比方说C=A^B^B,那C就等于A,用这个办法,就可以巧妙地解决这道题。
1 #include<stdio.h> 2 #include<bits/stdc++.h> 3 using namespace std; 4 int main() 5 { 6 int a=0,n,m; 7 cin>>n; 8 for(int i=0;i<n;i++) 9 { 10 scanf("%d",&m); 11 a^=m;//用异或求落单的筷子 12 } 13 cout<<a; 14 return 0; 15 }
第三题:高低位交换
高低位交换这道题其实是第一题进制转换的一个变型题目,只需要在进制转换的那两部中间加上一步交换高低位的操作就可以了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n; 4 char a[35],b[35],c[35]; 5 int main(){ 6 long long sum=0,i=0,j=0; 7 cin>>n; 8 while(1){ 9 a[j]=n%2+'0';//将数值转为字符 10 if(n/2==0){//跳出条件:余数为0 11 break; 12 } 13 n/=2; 14 j++; 15 } 16 int q=32; 17 while(q--){//倒叙赋值 18 if(a[q]==0){ 19 b[q]='0';//补0 20 }else{ 21 b[q]=a[q]; 22 } 23 } 24 int x=17,y=32; 25 while(x--){//交换低高位 26 c[y]=b[x]; 27 c[x]=b[y]; 28 y--; 29 } 30 int l=32; 31 while(l--){//循环,按权展开 32 sum+=(c[i]-'0')*pow(2,i);//如果不是字母, 将asll码值-‘0’的asll码值变成数字,然后在进行幂运算 33 i++;//将指数+1 34 } 35 cout<<sum; 36 return 0; 37 }
第四题:进制转换2
这道题是提高组的题,难度很大,也是进制转换的变形题,需要多一步对负数的处理,我研究了很长时间,查了各种书籍,才编了出来。所以无论是多难得题,只要认真去思考,一次次去尝试不放弃,就会成功。
1 #include<bits/stdc++.h> 2 using namespace std; 3 string ans; 4 int main(){ 5 int m,n,k,t,s; 6 while(cin>>m>>n){//输入 7 ans=""; 8 s=m; 9 while(m!=0){//循环,转进制 10 k=m%n;//取余 11 t=m/n; 12 if(k<0){//如果余数<0,把余数-进制,把商+1 13 k-= n; 14 t++; 15 } 16 m=t; 17 if(k>9){//将数值转化为字符串 18 ans+=k+55; 19 }else{ 20 ans+=k+'0'; 21 } 22 } 23 cout<<s<<"="; 24 for(int i=ans.length()-1;i>=0;i--){//倒序输出 25 cout<<ans[i]; 26 } 27 cout<<"(base"<<n<<")"<< endl; 28 } 29 return 0; 30 }
第五题:编号
这道题主要考察的知识点是排列组合,这道题的思路就是先将Maxnumber[i]排好序,然后利用加乘原理累乘算出结果。这道题需要注意数据类型要用long long int。“细节决定成败”这道题点醒了我,像这种数据类型之类的细节要多加注意!
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main(){ 4 long long int n,k=0,sum=1,b[55];//注意:数据类型用long long int!! 5 cin>>n; 6 while(k<n){//输入 7 cin>>b[k]; 8 k++; 9 } 10 sort(b,b+n);//排序 11 for(int i=0;i<n;i++){//累乘算结果 12 sum=sum*(b[i]-i); 13 sum%=1000000007; 14 } 15 cout<<sum; 16 return 0; 17 }
第六题:车的攻击
车的攻击这道题我从草稿纸上画了好多方格图去找规律,找算法。这道题用整体减空白的思路先求整体n*n,在求空白(整行方格数-行占用方格数)*(整列方格数-列占用方格数)就可以解决。这道题难度也很大,这就需要细心,认真的思考,尝试才行。
#include<bits/stdc++.h> using namespace std; long long a[1000005];//行坐标 long long b[1000005];//列坐标 int main(){ long long n,k; cin>>n>>k; //输入 for(int i=0;i<k;i++) { cin>>a[i]>>b[i]; } sort(a,a+k); //排序 sort(b,b+k); long long sum1=0,sum2=0;//计数器 for(int i=0;i<k;i++) { if(a[i]!=a[i+1])//如果没有在同一行,计数器+1 sum1++; if(b[i]!=b[i+1])//如果没有在同一列,计数器2+1 sum2++; } cout<<n*n-(n-sum1)*(n-sum2)<<endl;//用整体减空白,总面积N*N-(N-占用的行数)*(N-占用的列数)得出结果 return 0; }
总结
这次刷题让我学到了很多,不光有C++的知识,还有一些学习上的习惯、思维模式等等,其中我就明白了写代码也好,做文化课的题也罢,都需要一个认真、严谨的态度和努力钻研的决心,当然还需要有好的学习方法这样才能让自己做题的错误率大大减少。