蓝桥杯练习系统:
题1 :
刚开始的想法是将16进制转为十进制再转为二进制
看了题解之后发现不能这么操作,要先将十六进制转化为二进制之后将2进制转为8进制。
要点string 跟cin的应用。
#include<stdio.h>
# include<iostream>
#include<string.h>
# include<string>
using namespace std;
int n;
int main(){
scanf("%d",&n);
while(n -- ){
string st;
cin >> st;
string a;
for(int i = 0;i < st.length();i ++){
if(st[i] == '0') a+= "0000";
else if(st[i] == '1') a+= "0001";
else if(st[i] == '2') a+= "0010";
else if(st[i] == '3') a+= "0011";
else if(st[i] == '4') a+= "0100";
else if(st[i] == '5') a+= "0101";
else if(st[i] == '6') a+= "0110";
else if(st[i] == '7') a+= "0111";
else if(st[i] == '8') a+= "1000";
else if(st[i] == '9') a+= "1001";
else if(st[i] == 'A') a+= "1010";
else if(st[i] == 'B') a+= "1011";
else if(st[i] == 'C') a+= "1100";
else if(st[i] == 'D') a+= "1101";
else if(st[i] == 'E') a+= "1110";
else if(st[i] == 'F') a+= "1111";
}
int len = a.length();
if(len %3 == 1){//3位数为一组,凑够一组
a = "00" + a;
}
else if(len %3 == 2){
a = "0" + a;
}
int flag = 0;
int sum = 0;
for(int i = 2;i < a.length();i += 3){
sum = (a[i - 2] - '0')*4+(a[i - 1] - '0')*2+ (a[i] - '0');
if(sum != 0) flag = 1;
if(flag == 1){
printf("%d",sum);
}
}
printf("\n");
}
return 0;
}
对于string 和cin 的应用,特地在hdu上找了一题进行练习:
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1004
要点:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
map <string,int> num;
int n;
int main(){
while(scanf("%d",&n)&&(n != 0)){
int cnt = 0;
int count[1005];
memset(count,0,sizeof(count));
num.clear();
for(int i = 0;i < n;i ++){
string s;
cin >> s;
if(num.count(s) == 0){//之前没有在map里面
num[s] = cnt;
cnt ++;
count[num[s]] ++;
}
else{
count[num[s]] ++;
}
}
int position = max_element(count,count+cnt) - count;
string s;
map<string,int>::iterator it = num.begin();
while(it != num.end()){
if(it->second == position){
s = it->first;
break;
}
it ++;
}
cout << s << endl;
}
return 0;
}
map应用扩展:
题2:十六进制转十进制:
知识点三:回文数:
- hdu1282
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5;
long long n;
int a[maxn];
long long ans[maxn];
int top = 0;
int ishuiwei(int cnt){
for(int i = 0;i < cnt/2;i ++){
if(a[i] != a[cnt - 1- i]){
return false;
}
}
return true;
}
int main(){
while(scanf("%lld",&n) != EOF){
memset(ans ,0,sizeof(ans));
top = 0;
ans[top ++] = n;
int cnt = 0;
int cnt2 = 0;
while(n != 0){
a[cnt] = n%10;
n = n/10;
cnt++;
}
while(ishuiwei(cnt) == 0){
long long sum1 = 0;
for(int i = 0;i < cnt;i ++){
sum1 = sum1*10 + a[i];
}
long long sum2 = 0;
for(int i = cnt - 1;i >= 0;i --){
sum2 = sum2*10 + a[i];
}
long long sum = sum1 + sum2;
cnt = 0;
n = sum;
while(n != 0){
a[cnt] = n%10;
n = n/10;
cnt ++;
}
ans[top ++] = sum;
cnt2 ++;
}
printf("%d\n",cnt2);
printf("%lld",ans[0]);
for(int i = 1;i < top;i ++){
printf("--->%lld",ans[i]);
}
printf("\n");
}
return 0;
}
知识点:大数处理:
https://www.cnblogs.com/wzjhoutai/p/7265194.html
- hdu 1002
用数组进行模拟
好累
写的很乱
#include<stdio.h>
#include<string>
#include<string.h>
using namespace std;
const int maxn = 1005;
int t;
char s1[maxn];
char s2[maxn];
int a1[maxn];
int a2[maxn];
int ans[maxn];
int main(){
scanf("%d",&t);
int cnttt = 1;
while(t -- ){
scanf("%s",&s1);
scanf("%s",&s2);
int len1 = strlen(s1);
int len2 = strlen(s2);
int b = 0;
if(cnttt > 1)
printf("\n");
printf("Case %d:\n",cnttt);
cnttt ++;
for(int i = 0;i < len1;i ++){
a1[i] = s1[i] - '0';
printf("%d",a1[i]);
}
printf(" + ");
for(int i = 0;i < len2;i ++){
a2[i] = s2[i] - '0';
printf("%d",a2[i]);
}
printf(" = ");
int ma = 0,mi = 0;
if(len1 > len2){
b = 1;
ma = len1;
mi = len2;
}
else if(len1 < len2){
b = 2;
ma = len2;
mi = len1;
}
else{
b = 0;
ma = len2;
mi = len1;
}
// printf("b = %d\n",b);
int cinn = 0;//表示进位
for(int i = 0;i < mi;i ++){
int a = a1[len1 - 1 - i] +a2[len2 - 1 - i] + cinn;
cinn = 0;
if(a >= 10){
cinn = 1;
a = a - 10;
}
ans[ma - 1 - i] = a;
// printf("ans = %d\n",ans[ma - 1 - i]);
}
if(b == 1){
for(int i = len1 - mi - 1;i >= 0;i --){
int a = a1[i] + cinn;
cinn = 0;
if(a >= 10){
cinn = 1;
a = a - 10;
}
ans[i] = a;
}
}
else if(b == 2){
for(int i = len2 - mi - 1;i >= 0;i --){
int a = a2[i] + cinn;
// printf(" i = %d,b = 2:a = %d\n",i,a);
cinn = 0;
if(a >= 10){
cinn = 1;
a = a - 10;
}
ans[i] = a;
}
}
else if(b == 0){
if(cinn == 1)
printf("1");
int flag = 0;//排掉不为0
for(int i = 0;i < ma;i ++){
if(ans[i] != 0){
flag = 1;
}
if(flag == 1)
printf("%d",ans[i]);
}
printf("\n");
continue;
}
int flag = 0;
if(cinn == 1){
printf("1");
flag = 1;
}
for(int i = 0;i < ma;i ++){
if(ans[i] != 0){
flag = 1;
}
if(flag == 1)
printf("%d",ans[i]);
}
printf("\n");
}
return 0;
}
/*
1
119999 999
*/
- hdu 1042
传送门:https://www.cnblogs.com/blumia/p/hdu1042.html
我感觉这个博主的模板写的挺好的
#include<stdio.h>
using namespace std;
const int maxn = 10005;
int n;
char s[maxn];
void factorial(){
int a[500000] = {1};
int carry,j;
int digit = 1;
for(int i = 2;i <= n;i ++){
for(j = 0,carry = 0;j < digit;j ++){
int temp = a[j] * i + carry;//模拟相乘+进位
a[j] = temp % 10 ;
carry = temp / 10;
}
//相乘结束,开始处理对应的进位
while(carry != 0){
a[++digit - 1] = carry%10;
carry = carry/ 10;
}
}
//开始打印;
for(int i = digit - 1;i >= 0;i --){
printf("%d",a[i]);
}
printf("\n");
}
int main(){
while(scanf("%d",&n) != EOF){
factorial();
}
return 0;
}
- hdu 1047
这个方法比我自己写的好很多,还是应该多看别人的实例。
#include<stdio.h>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn =5;
int t ;
string myadd(string str1,string str2){
int len1 = str1.length();
int len2 = str2.length();
string ans;
// printf("len1 = %d,len2 = %d\n",len1,len2);
if(len1 < len2){//字符串1的长度小于字符串2的长度,将其 补0
for(int i = 0;i < len2 - len1;i ++){
str1 = '0' + str1;
}
}
else{
for(int i = 0;i < len1 - len2;i ++){
str2 = '0' + str2;
}
}
// cout << "str1:"<<str1 << endl;
// cout << "str2:"<<str2 << endl;
int carry = 0;
len1 = str1.length();
for(int i = len1 - 1;i >= 0;i --){//开始诸位相加
int temp = (str1[i] - '0' ) + (str2[i] - '0') + carry;
// printf("temp = %d\n",temp);
carry = temp / 10;
temp = temp %10;
ans = char(temp + '0') + ans;
}
if(carry != 0){
ans = char(carry + '0') + ans;
}
// cout << "ans:"<<ans << endl;
return ans;
}
int main(){
scanf("%d",&t);
while(t -- ){
string sum = "0";
string s;
while(cin >> s){
if(s == "0")
break;
sum = myadd(sum,s);
// cout << sum << endl;
}
cout << sum << endl;
if(t > 0)
cout << endl;
}
}
/*
2
123456789012345678901234567890
123456789012345678901234567890
123456789012345678901234567890
0
123456789012345678901234567890000000000
123456789012345678901234567890000000000
123456789012345678901234567890000000000
0
*/
- hdu1715
试图打表,然后失败
tle代码:
#include<stdio.h>
#include<string>
#include<string.h>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn = 1005;
long long dp[maxn];
int t;
string myadd(string str1,string str2){
string str;
int len1 = str1.length();
int len2 = str2.length();
if(len1 > len2){
for(int i = 0 ;i < len1 - len2;i ++){
str2 = '0'+ str2;
}
}
else{
for(int i = 0 ;i < len2 - len1;i ++){
str1 = '0'+ str1;
}
}
len1 = str1.length();
// printf("len1 = %d,len2 = %d",len1,len2);
int carry = 0;
for(int i = len1 - 1;i >= 0;i -- ){
int temp = (str1[i] - '0') + (str2[i] - '0') + carry;
carry = temp/10;
temp = temp%10;
str = char(temp + '0')+ str;
}
if(carry != 0){
str = char(carry + '0')+ str;
}
// cout << "str:" << str << endl;
return str;
}
int main(){
//得到n< 80之下的答案 dp[79] = 23416728348467685
dp[0] = 1;
dp[1] = 1;
for(int i = 2;i < 80;i ++){
dp[i] = dp[i - 1]+ dp[i - 2];
}
string str1 = "14472334024676221";//f[79]的数
string str2 = "23416728348467685";//f[80]的数
scanf("%d",&t);
int n;
while(t --){
scanf("%d",&n);
if(n <= 80){
printf("%lld\n",dp[n-1]);
continue;
}
else{
int t = n - 80;
// printf("t = %d\n",t);
string sum;
while(t --){
sum = myadd(str1,str2);
// cout <<"sum1:" << sum << endl;
str1 = str2;
str2 = sum;
}
cout << sum << endl;
}
}
return 0;
}
/*
13
81
14
55
234
999
1
2
3
4
5
6
7
8
*/
最后还是打表过的,窒息:
#include<stdio.h>
#include<string>
#include<string.h>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn = 1005;
long long dp[maxn];
int t;
string ans[maxn];
string myadd(string str1,string str2){
string str;
int len1 = str1.length();
int len2 = str2.length();
if(len1 > len2){
for(int i = 0 ;i < len1 - len2;i ++){
str2 = '0'+ str2;
}
}
else{
for(int i = 0 ;i < len2 - len1;i ++){
str1 = '0'+ str1;
}
}
len1 = str1.length();
// printf("len1 = %d,len2 = %d",len1,len2);
int carry = 0;
for(int i = len1 - 1;i >= 0;i -- ){
int temp = (str1[i] - '0') + (str2[i] - '0') + carry;
carry = temp/10;
temp = temp%10;
str = char(temp + '0')+ str;
}
if(carry != 0){
str = char(carry + '0')+ str;
}
// cout << "str:" << str << endl;
return str;
}
int main(){
//得到n< 80之下的答案 dp[79] = 23416728348467685
ans[1] = "1";
ans[2] = "1";
string str1 ;//f[79]的数
string str2;//f[80]的数
for(int i = 3;i <= 1000;i ++){
str1 = ans[i - 2];
str2 = ans[i - 1];
ans[i] = myadd(str1,str2);
}
scanf("%d",&t);
int n;
while(t --){
scanf("%d",&n);
cout << ans[n] << endl;
}
return 0;
}
/*
13
81
14
55
234
999
1
2
3
4
5
6
7
8
*/
- hdu 1063
快速幂。告辞了,不会写,等裤子帮我写吧
真香,然后7.2一边玩一边写
我感觉写的很对啊,但是就是跑到一半程序就崩溃了
#include<stdio.h>
#include<string>
#include<string.h>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 605;
char s[40];
int n;
int ans[maxn];
string str1;
string str2;
string sum;
//乘法模板
string myplus(string str1,string str2){
sum.clear();
memset(ans,0,sizeof(ans));
int carry;//表示进位
for(int i = 0;i < str1.length();i ++){
for(int j = 0;j < str2.length() ;j ++){
ans[i + j] += (str1[i] - '0')*(str2[j] - '0');
// printf("a [%d] = %d * %d",i + j,(str1[i] - '0'),(str2[j] - '0'));
// printf("= %d\n",ans[i + j]);
}
}
for(int i = 0;i < str1.length() + str2.length() - 1;i ++){
carry = ans[i] / 10;
ans[i + 1] += carry;
ans[i] %= 10;
sum = char(ans[i] + '0') + sum;
}
while(carry != 0){
sum = char((carry % 10)+ '0') + sum;
carry = carry/10;
}
return sum;
}
int main(){
while(scanf("%s %d",&s,&n) != EOF){
str1.clear();
str2.clear();
int len = strlen(s);
int xs = 0;
int isxs = 0;
int digit = str1.length();
for(int i = 0;i < len;i ++){//统计小数的个数
if(s[i] == '.'){
xs = i;
break;
}
}
int flag = 0;
for(int i = len - 1;i >= 0;i --){//统计小数的个数
if(s[i] != '0'){
flag = 1;
}
if(flag == 1)
if((s[i] >= '0')&&(s[i] <= '9')){
str1 += s[i];
}
}
str2 = str1;
// printf("len = %d,strlen = %d %d\n",len,str1.length(),str2.length());
//得到小数的位数
xs = str1.length() - xs ;
// printf("len - xs - 1 = %d\n",len - xs - 1);
if(len - xs - 1 == 1){
if(s[0] == '0') isxs = 1;
}
string sum;
n = n -1;
int point = xs;
// printf("point = %d\n",point);
while(n -- ){
// cout << "str1 : " << str1 << endl;
// cout << "str2 : " << str2 << endl;
sum = myplus(str2,str1);
reverse(sum.begin(),sum.end());
str2 = sum;
point += xs;
}
reverse(sum.begin(),sum.end());
// printf("isxs = %d\n",isxs);
if(isxs == 0)
for(int i = 0;i < sum.length()- point;i ++){
cout << sum[i];
}
cout << "." ;
for(int i = sum.length()- point;i < sum.length();i ++){
cout << sum[i];
}
cout << endl ;
}
return 0;
}
/*
2.2 3
*/
后来爸爸靠自己AC了,tmd
#include<stdio.h>
#include<string>
#include<string.h>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
const int maxn = 605;
char s[40];
int n;
int ans[maxn];
string str1;
string str2;
string sum;
//乘法模板
string myplus(string str1,string str2){
sum.clear();
memset(ans,0,sizeof(ans));
int carry;//表示进位
for(int i = 0;i < str1.length();i ++){
for(int j = 0;j < str2.length() ;j ++){
ans[i + j] += (str1[i] - '0')*(str2[j] - '0');
// printf("a [%d] = %d * %d",i + j,(str1[i] - '0'),(str2[j] - '0'));
// printf("= %d\n",ans[i + j]);
}
}
for(int i = 0;i < str1.length() + str2.length() - 1;i ++){
carry = ans[i] / 10;
ans[i + 1] += carry;
ans[i] %= 10;
sum = char(ans[i] + '0') + sum;
}
while(carry != 0){
sum = char((carry % 10)+ '0') + sum;
carry = carry/10;
}
// cout << " sum:" << sum << endl;
return sum;
}
int main(){
while(scanf("%s %d",&s,&n) != EOF){
int iszs = 0;
int isxs = 0;
if(n == 0){
cout << "1" << endl;
continue;
}
int len = strlen(s);
str1.clear();
//筛掉前面的0
int flag = 0;
for(int i = 0;i < len;i ++){
if(s[i] != '0'){
flag = 1;
}
if(flag == 1){
str1 += s[i];
}
}
str2.clear();
str2 = str1;
//统计小数位数
int pos = -1;
for(int i = 0;i < str1.length();i ++){
if(str1[i] == '.'){
pos = i;
break;
}
}
if(pos == -1){
iszs = 1;
}
if(iszs == 0){
// cout << str1 << endl;
//筛掉后面的0
flag = 0;
str2.clear();
for(int i = str1.length() - 1;i >= 0;i --){
if(str1[i] != '0'){
// cout << str1[i] << endl;
flag = 1;
}
if(flag == 1){
str2 = str1[i] + str2;
}
}
str1 = str2;
}
//统计小数位数
pos = -1;
for(int i = 0;i < str1.length();i ++){
if(str1[i] == '.'){
pos = i;
break;
}
}
// printf("pos = %d\n",pos);
//没有发现小数点,是整数
if((pos == -1)||(pos == str1.length() - 1)){
iszs = 1;
}
//第一位就是小数点, 是小数
if(pos == 0){
isxs = 1;
}
int xsnum = 0;
// printf("strlen = %d,pos = %d\n",str1.length(),pos);
xsnum = str1.length() -1 - pos ;
//筛掉小数点
str2.clear();
for(int i = str1.length() - 1;i >= 0;i --){
if((str1[i] >= '0')&&(str1[i] <= '9')){
str2 += str1[i];
}
}
str1 = str2;
str2 = "1";
// cout << "srt1:" << str1 << endl;
string sum;
int point = 0;
// printf("point = %d,xsnum = %d\n",point,xsnum);
while(n -- ){
// cout << "str1 : " << str1 << endl;
// cout << "str2 : " << str2 << endl;
sum = myplus(str2,str1);
reverse(sum.begin(),sum.end());
str2 = sum;
point += xsnum;
}
reverse(sum.begin(),sum.end());
// cout << "sum:" << sum << endl;
if(iszs == 1){
cout << sum << endl;
continue;
}
if(isxs == 0){
for(int i = 0;i < sum.length()- point;i ++){
cout << sum[i];
}
cout << "." ;
for(int i = sum.length()- point;i < sum.length();i ++){
cout << sum[i];
}
cout << endl;
continue;
}
if(isxs == 1){
int t = sum.length();
// printf("point = %d,sum.length() = %d\n",point,sum.length());
if(point > t){
for(int i = 0;i < point - t;i ++){
// cout << "sum:" << sum << endl;
sum = '0' + sum;
}
}
cout << "." << sum << endl;
}
}
return 0;
}
/*
001.10 2
000.01 0
011.01 3
000.00 2
000000 2
00000. 2
0.0100 2
99.999 0
*/
- hdu1316
大数计算
斐波那契数
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
const int maxn = 105;
const int maxm = 500;
char a[maxn],b[maxn];
string fb[maxm];
string countfb(string str1,string str2){
string sum;
int len1 = str1.length();
int len2 = str2.length();
if(len1 > len2)
for(int i = 0;i < len1 - len2;i ++)
str2 = '0' + str2;
else
for(int i = 0;i < len2 - len1;i ++)
str1 = '0' + str1;
int carry = 0;
for(int i = str1.length() - 1;i >= 0;i -- ){
int temp = (str1[i] -'0') + (str2[i] -'0') + carry;
sum = char((temp % 10) + '0')+sum;
carry = temp / 10;
}
if(carry != 0){
sum = char(carry + '0') +sum;
}
return sum;
}
int smallthanA(){
int cnt = 0;
int lena = strlen(a);
int flag = 0;
int cnt2 = 0;
for(int i = 1;i < maxm;i ++){
flag = 0;
if(lena > fb[i].length()){
// cout <<"fb1:"<<fb[i]<< endl;
cnt ++;
continue;
}
else if(lena < fb[i].length())
break;
else{
if(a == fb[i]) continue;
for(int j = 0;j < lena;j ++){
if((a[j]- '0') > (fb[i][j] - '0'))
break;
if((a[j]- '0') < (fb[i][j] - '0')){
flag = 1;
break;
}
}
if(flag == 0){
// cout <<"fb:2"<<fb[i]<< endl;
cnt++;
}
if(flag == 1){
break;
}
}
}
return cnt;
}
int largethanB(){
int cnt = 0;
int lenb = strlen(b);
int flag = 0;
for(int i = maxm - 1;i >= 0;i --){
flag = 0;
if(lenb < fb[i].length()){
cnt ++;
continue;
}
else if(lenb > fb[i].length()) break;
else{
if(b == fb[i]) continue;
for(int j = 0;j < lenb;j ++){
if((b[j]- '0') < (fb[i][j] - '0'))
break;
if((b[j]- '0') > (fb[i][j] - '0')){
flag = 1;
break;
}
}
if(flag == 0){
cnt++;
}
if(flag == 1){
break;
}
}
}
return cnt;
}
int main(){
fb[1] = "1";
fb[2] = "2";
for(int i = 3;i < maxm;i ++){
fb[i] = countfb(fb[i - 1],fb[i - 2]);
// cout << fb[i] << endl;
}
while(scanf("%s %s",&a,&b)){
if((a[0] == '0')&&(b[0] == '0')){
break;
}
int cnt1 = smallthanA();
// printf("cnt = %d\n",cnt1);
int cnt2 = largethanB();
// printf("cnt = %d\n",cnt2);
int ans = maxm - 1 - cnt1 - cnt2;
printf("%d\n",ans);
}
return 0;
}
/*
0 1
*/
- hdu 1753
https://paste.ubuntu.com/p/5xgtzjZgCj/