CSP-J刷题记录文档
基础算法
8.字符串
8.1 字符型
8.2 字符串基础
1115. 数字和
#include<bits/stdc++.h>
using namespace std;
int main(){
string a;
int sum=0;
cin>>a;
for(int i=0;i<a.size();i++){
sum += (a[i]-'0');
}
cout<<sum;
return 0;
}
8.3 字符串进阶
1100. 词组缩写
#include<bits/stdc++.h>
using namespace std;
int main(){
string a;
while(cin>>a)
{
char c = toupper(a[0]);
cout<<c;
}
}
10.进制转换
任何进制都没有他的本身:因为他们是从0开始的
10进制:
0 1 2 3 4 5 6 7 8 9 10 11
2进制:
0 1 10 11 100 101 110 111 1000
8进制:
0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20
16进制:
0 1 2 3 4 5 6 7 8 9 A B C D E F
10 11 12 13 14 15 16 17 18 19 1A
1B 1C 1D 1E 1F 20 21 22 23 24 25
(1)10进制转R进制(任意进制的意思):采用除R取余法
如果转成10进制,就除以10
如果转成2进制,就除以2
易错点:从后往前读
(2)R进制转10进制:按权展开
所谓权就是:主要看R进制,R进制如果是10进制,那么权就是10的多少次方,如果R进制是2进制,那么权就是2的多少次方。(记得从低位开始)
注意:任何进制的0次方都是1
简便方法:2进制转10进制
例子:1010 转成10进制
1 0 1 0
8 4 2 1
将有1 的地方对应的数加起来 得到:8+2=10
假设是6位2进制数:101010
1 0 1 0 1 0
32 16 8 4 2 1
对应的1加起来:32+8+2=42
10.1 10进制和R进制互转
1108 - 正整数N转换成一个二进制数
#include<bits/stdc++.h>
using namespace std ;
string s;
int r,t=1,i;
int main(){
cin>>s;
for(i=s.size()-1;i>=0;i--){
r=r+(s[i]-'0')*t;
t=t*2;
}
cout<<r;
}
1290 - 二进制转换十进制
#include<bits/stdc++.h>
using namespace std;
string s;
int r,t=1;
int main(){
cin>>s;
for(int i=s.size()-1;i>=0;i--){
r=r+(s[i]-'0')*t;
t=t*2;
}
cout<<r;
}
1292 - 十六进制转十进制
#include<bits/stdc++.h>
using namespace std;
string s;
long long r,t=1;
int main(){
cin>>s;
for(int i=s.size()-1;i>=0;i--){
if(isdigit(s[i])){
r=r+(s[i]-'0')*t;
}else{
r=r+(s[i]-'A'+10)*t;
}
t=t*16;
}
cout<<r;
}
1288 - 正整数n转换为8进制
#include<bits/stdc++.h>
using namespace std;
long long sum=0,b=1,x=1;
long long a;
int main()
{
cin>>a;
while(a!=0)
{
sum=sum+(a%8)*x;
a/=8;
x*=10;
}
cout<<sum<<endl;
return 0;
}
1289 - 正整数n转换为16进制
#include<bits/stdc++.h>
using namespace std;
long long n,x;
string s;
char c;
int main(){
cin>>n;
while(n!=0){
x=n%16;
if(x<10){
c=x+'0';
}else{
c=x+'A'-10;
}
s=c+s;
n=n/16;
}
if(s==""){
cout<<0;
}else{
cout<<s;
}
}
10.2 2进制和8/16进制互转
1306 - 十六进制转二进制
#include<bits/stdc++.h>
using namespace std;
string t[16]={"0000","0001","0010","0100","0101","0110","0111","1000","1000","1001","1010","1011","1100","1101","1110","1111"};
int main(){
string s,r;
cin>>s;
int x;
for(int i=0;i<s.size();i++){
if(isdigit(s[i])){
x=s[i]-'0';
}else{
x=s[i]-'A'+10;
}
r=r+t[x];
}
while(r[0]=='0'){
r.erase(0,1);
}
if(r==""){
cout<<0;
}else{
cout<<r;
}
}
1294 - 二进制转十六进制
#include<bits/stdc++.h>
using namespace std;
char num(string s){
int r=0,t=1;
for(int i=s.size()-1;i>=0;i--){
r=r+(s[i]-'0')*t;
t=t*2;
}
char c;
if(r<10){
c=r+'0';
}else{
c=r+'A'-10;
}
return c;
}
int main(){
string s,t;
cin>>s;
if(s.size()%4==1){
s="000"+s;
}else if(s.size()%4==2){
s="00"+s;
}else if(s.size()%4==1){
s="0"+s;
}
for(int i=0;i<s.size();i=i+4){
t=s.substr(i,4);
cout<<num(t);
}
}
10.3 额外训练
1386 . 小丽找半个回文数
思路:任何进制的转换函数
1、定义一个数组
2、采用while获取获取值不为0
3、取出对应进制的余数
4、计数
5、得到对应进制的商
#include<bits/stdc++.h>
using namespace std;
bool huiwen(int n,int d){
bool r=true;
int k=0;
int a[1000]={0};
while(n!=0){
a[k]=n%d;
k++;
n=n/d;
}
for(int i=0;i<k/2;i++){
if(a[i]!=a[k-i-1]){
r=false;
break;
}
}
return r;
}
int main(){
int a[110],n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
if(huiwen(a[i],10)==false&&(huiwen(a[i],16)==true)||(huiwen(a[i],2)==true)){
cout<<a[i]<<endl;
}
}
return 0;
}
11.1高精度运算基础
1287. 高精度乘双精度
#include<bits/stdc++.h>
using namespace std;
string s1,s2;
int a[250],b[250],c[500];
int p;
int main(){
cin>>s1>>s2;
for(int i=0;i<s1.size();i++){
a[i]=s1[s1.size()-i-1]-'0';
}
for(int i=0;i<s2.size();i++){
b[i]=s2[s2.size()-i-1]-'0';
}
for(int i=0;i<s1.size();i++){
for(int j=0;j<s2.size();j++){
c[i+j]=c[i+j]+a[i]*b[j];
if(c[i+j]>=10){
c[i+j+1]=c[i+j+1]+c[i+j]/10;
c[i+j]=c[i+j]%10;
}
}
}
for(int i=s1.size()+s2.size()-1;i>=0;i--){
if(c[i]!=0){
p=i;
break;
}
}
for(int i=p;i>=0;i--){
cout<<c[i];
}
}
1286. 高精度乘单精度
#include<bits/stdc++.h>
using namespace std;
string s1;
int a[250],b;
int main(){
cin>>s1>>b;
for(int i=0;i<s1.size();i++){
a[i]=s1[s1.size()-i-1]-'0';
}
for(int i=0;i<s1.size();i++){
a[i]=a[i]*b;
}
for(int i=0;i<s1.size()+4;i++){
if(a[i]>=10){
a[i+1]=a[i+1]+a[i]/10;
a[i]=a[i]%10;
}
}
int len=s1.size()+4;
while(a[len]==0 && len>0){
len--;
}
for(int i=len;i>=0;i--){
cout<<a[i];
}
return 0;
}
1268. 高精度加法
#include<bits/stdc++.h>
using namespace std;
string s1,s2;
int a[250],b[250],c[500];
int main(){
cin>>s1>>s2;
for (int i=0;i<s1.size();i++){
a[i]=s1[s1.size()-i-1]-'0';
}
for (int i=0;i<s2.size();i++){
b[i]=s2[s2.size()-i-1]-'0';
}
int len=max(s1.size(),s2.size());
for(int i=0;i<len;i++){
c[i]=a[i]+b[i];
}
for(int i=0;i<len;i++){
if(c[i]>=10){
c[i+1]+=c[i]/10;
c[i]=c[i]%10;
}
}
while(c[len] == 0 && len>0){
len--;
}
for(int i=len;i>=0;i--){
cout<<c[i];
}
return 0;
}
1269. 高精度减法
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s1, s2;
int a[250], b[250], c[250];
int len1, len2;
memset(a, 0, sizeof(a) / sizeof(int));
memset(b, 0, sizeof(b) / sizeof(int));
memset(c, 0, sizeof(c) / sizeof(int));
cin >> s1 >> s2;
if (s1 == s2)
{
cout << "0";
return 0;
}
len1 = s1.size();
len2 = s2.size();
char op = '+';
if (len2 > len1 || len2 == len1 && s2 > s1)
{
op = '-';
swap(s1, s2);
}
for (int i = 0; i < s1.size(); i++)
{
a[i] = s1[s1.size() - i - 1] - '0';
}
for (int i = 0; i < s2.size(); i++)
{
b[i] = s2[s2.size() - i - 1] - '0';
}
for (int i = 0; i < s1.size(); i++)
{
if (a[i] < b[i])
{
a[i] = 10 + a[i];
a[i + 1]--;
}
c[i] = a[i] - b[i];
}
int sp = 0;
for (int i = s1.size() - 1; i >= 0; i--)
{
if (c[i] != '0')
{
sp = i;
}
}
if (op == '-')
{
cout << op;
}
if (c[s1.size() - 1] == 0)
{
for (int i = s1.size() - 2; i >= sp; i--)
{
cout << c[i];
}
}
else
{
for (int i = s1.size() - 1; i >= sp; i--)
{
cout << c[i];
}
}
return 0;
}