您的位置:首页 > 编程语言 > C语言/C++

第四届蓝桥杯C++本科B组预赛解题报告

2013-05-27 19:54 567 查看

第四届蓝桥杯C++本科B组解题报告

-转自themagickeyjianan的专栏

分类:
蓝桥杯 2013-05-19 15:53
294人阅读 评论(0)收藏
举报

<1> 高斯日记

1799-7-16

[java]
view plaincopyprint?

package JiaNan;
import java.util.Calendar;

import java.util.GregorianCalendar;
public class GaoSiRiJi
{
static Calendar c = new GregorianCalendar(1791,12-1,15);
public staticvoid main(String args[])

{
c.add(Calendar.DATE,8113-5343);
System.out.println(c.get(Calendar.YEAR)+"-"+c.get(Calendar.MONTH)+"-"+c.get(Calendar.DATE));
}
}

/*
1799-7-16 //注意:Java中月份是从0开始的,因此虽然输出是1799-6-16,但是要写成1799-7-16
*/

package JiaNan;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class GaoSiRiJi
{
static  Calendar c = new GregorianCalendar(1791,12-1,15);
public static void main(String args[])
{
c.add(Calendar.DATE,8113-5343);
System.out.println(c.get(Calendar.YEAR)+"-"+c.get(Calendar.MONTH)+"-"+c.get(Calendar.DATE));
}
}

/*
1799-7-16      //注意:Java中月份是从0开始的,因此虽然输出是1799-6-16,但是要写成1799-7-16
*/


<2>马虎的算式

142

方法1:高层循环,穷举法

[java]
view plaincopyprint?

package JiaNan;
public class MaHuDeSuanShi
{
static int kinds =0;

static void f()
{
for(int a =1; a <=
9;a++)
for(int b =1; b <=
9;b++)
for(int c =1; c <=
9;c++)
for(int d =1; d <=
9;d++)
for(int e =1; e <=
9;e++)
{
int ab = 10*a + b;
int cde = 100*c +10*d + e;

int adb =
100*a + 10*d + b;
int ce = 10*c + e;
if(ab*cde != adb*ce)
continue;

int num[] = newint[10];
num[a]++;
num++;
num[c]++;
num[d]++;
num[e]++;
int i;
for(i = 1;i <=9;i++)

{
if(num[i] >
1)
break;
}

if(i == 10)
{
//System.out.println(ab+"*"+cde+"="+adb+"*"+ce);
kinds++;
}
}
}
public staticvoid main(String args[])

{
long start = System.nanoTime();
f();
System.out.println(kinds);
long end = System.nanoTime();
System.out.println("运行时间:"+(end-start)/Math.pow(10,9)+"s");
}
}

/*
142
运行时间:0.010208086s
*/

package JiaNan;
public class MaHuDeSuanShi
{
static int kinds = 0;
static void f()
{
for(int a = 1; a <= 9;a++)
for(int b = 1; b <= 9;b++)
for(int c = 1; c <= 9;c++)
for(int d = 1; d <= 9;d++)
for(int e = 1; e <= 9;e++)
{
int ab = 10*a + b;
int cde = 100*c + 10*d + e;
int adb = 100*a + 10*d + b;
int ce = 10*c + e;
if(ab*cde != adb*ce)
continue;

int num[] = new int[10];
num[a]++;
num[b]++;
num[c]++;
num[d]++;
num[e]++;
int i;
for(i = 1;i <= 9;i++)
{
if(num[i] > 1)
break;
}

if(i == 10)
{
//System.out.println(ab+"*"+cde+"="+adb+"*"+ce);
kinds++;
}
}
}
public static void main(String args[])
{
long start = System.nanoTime();
f();
System.out.println(kinds);
long end = System.nanoTime();
System.out.println("运行时间:"+(end-start)/Math.pow(10, 9)+"s");
}
}

/*
142
运行时间:0.010208086s
*/


方法2:运用排列,进行穷举法

[b][java]

view plaincopyprint?

package JiaNan;
public class MaHuDeSuanShi
{
static int kinds =0;

static int c[] =new
int[6];//枚举排列

static boolean vis[] =new
boolean[10];//记录是否被访问

static void check(int c[])
{
int ab = c[1]*10 + c[2];
int cde = c[3]*100 + c[4]*10 + c[5];
int adb = c[1]*100 + c[4]*10
+ c[2];
int ce = c[3]*10 + c[5];
if(ab*cde == adb*ce)
{
//System.out.println(ab+"*"+cde+"="+adb+"*"+ce);
kinds++;
}
}
static void dfs(int start,int n)
{
if(start ==
6)
{
check(c);
return;
}
for(int i =1;i <= n;i++)

{
if(!vis[i])
{
c[start] = i;
vis[i] = true;

dfs(start+1,n);
vis[i] = false;

c[start] = 0;
}
}
}
public staticvoid main(String args[])

{
long start = System.nanoTime();
dfs(1,9);
System.out.println(kinds);
long end = System.nanoTime();
System.out.println("运行时间:"+(end-start)/Math.pow(10,9)+"s");
}
}

/*
142
运行时间:0.002564503s
*/
//备注:由此可见,排列是一种比较高效率的算法,大约效率是循环穷举的5倍。由此想到21位水仙花也是利用排列做的,效率都非常高

package JiaNan;
public class MaHuDeSuanShi
{
static int kinds = 0;
static int c[] = new int[6];         //枚举排列
static boolean vis[] = new boolean[10];  //记录是否被访问
static void check(int c[])
{
int ab = c[1]*10 + c[2];
int cde = c[3]*100 + c[4]*10 + c[5];
int adb = c[1]*100 + c[4]*10 + c[2];
int ce = c[3]*10 + c[5];
if(ab*cde == adb*ce)
{
//System.out.println(ab+"*"+cde+"="+adb+"*"+ce);
kinds++;
}
}
static void dfs(int start,int n)
{
if(start == 6)
{
check(c);
return;
}
for(int i = 1;i <= n;i++)
{
if(!vis[i])
{
c[start] = i;
vis[i] = true;
dfs(start+1,n);
vis[i] = false;
c[start] = 0;
}
}
}
public static void main(String args[])
{
long start = System.nanoTime();
dfs(1,9);
System.out.println(kinds);
long end = System.nanoTime();
System.out.println("运行时间:"+(end-start)/Math.pow(10, 9)+"s");
}
}

/*
142
运行时间:0.002564503s
*/
//备注:由此可见,排列是一种比较高效率的算法,大约效率是循环穷举的5倍。由此想到21位水仙花也是利用排列做的,效率都非常高


<3>39台阶

51167078

[java]
view plaincopyprint?

package JiaNan;
public class _39TaiJie
{
static int kinds =0;

static int c[] =new
int[40];//最多走39步

static int choice[] =new
int[]{1,2};
static void dfs(int start,int n)
{
if(n <= 0)
{
if(n==0 && start%2==0)
{
kinds++;
}
return;
}
for(int i =0;i <=
1;i++)
{
c[start] = choice[i];
dfs(start+1,n-choice[i]);
//对比上一题,总结何时需要恢复:当要避免重复时就需要vis数组记录一下避免重复,还有韩信走马分酒问题也是用了vis

}
}
public staticvoid main(String args[])

{
long start = System.nanoTime();
dfs(0,39);
System.out.println(kinds);
long end = System.nanoTime();
System.out.println("运行时间:"+(end-start)/Math.pow(10,9)+"s");
}
}

/*
51167078
运行时间:5.390165205s
*/

package JiaNan;
public class _39TaiJie
{
static int kinds = 0;
static int c[] = new int[40];   //最多走39步
static int choice[] = new int[]{1,2};
static void dfs(int start,int n)
{
if(n <= 0)
{
if(n==0 && start%2==0)
{
kinds++;
}
return;
}
for(int i = 0;i <= 1;i++)
{
c[start] = choice[i];
dfs(start+1,n-choice[i]);        //对比上一题,总结何时需要恢复:当要避免重复时就需要vis数组记录一下避免重复,还有韩信走马分酒问题也是用了vis
}
}
public static void main(String args[])
{
long start = System.nanoTime();
dfs(0,39);
System.out.println(kinds);
long end = System.nanoTime();
System.out.println("运行时间:"+(end-start)/Math.pow(10, 9)+"s");
}
}

/*
51167078
运行时间:5.390165205s
*/


<4>黄金连分数

0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497050372347293136948

算法思想:在用递归f(n) = 1/(1+f(n-1));求解的过程中一直精确到300位,在最后输出时,再四舍五入到100位,这样将精度损失避免到最小

[java]
view plaincopyprint?

package JiaNan;
import java.math.BigDecimal;

import java.math.MathContext;
public class HuangJinLianFenShu
{
static BigDecimal f(int n)
{
if(n == 1)
return BigDecimal.valueOf(1.0);
return BigDecimal.valueOf(1.0).divide(new BigDecimal(BigDecimal.valueOf(1.0).add(f(n-1)).toString()),new
MathContext(300));
}
public staticvoid main(String args[])

{
long start = System.nanoTime();
BigDecimal des = new BigDecimal(f(200).toString(),new MathContext(100));
System.out.println(des);
long end = System.nanoTime();
System.out.println("运行时间:"+(end-start)/Math.pow(10,9)+"s");
}
}
/*
0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497050372347293136948
运行时间:0.08024721s
*/

package JiaNan;
import java.math.BigDecimal;
import java.math.MathContext;
public class HuangJinLianFenShu
{
static BigDecimal f(int n)
{
if(n == 1)
return BigDecimal.valueOf(1.0);
return BigDecimal.valueOf(1.0).divide(new BigDecimal(BigDecimal.valueOf(1.0).add(f(n-1)).toString()),new MathContext(300));
}
public static void main(String args[])
{
long start = System.nanoTime();
BigDecimal des = new BigDecimal(f(200).toString(),new MathContext(100));
System.out.println(des);
long end = System.nanoTime();
System.out.println("运行时间:"+(end-start)/Math.pow(10, 9)+"s");
}
}
/*
0.6180339887498948482045868343656381177203091798057628621354486227052604628189024497050372347293136948
运行时间:0.08024721s
*/


<5>前缀判断

*haystack++ != *needle++

[cpp]
view plaincopyprint?

#include<iostream>
using namespace std;
char* prefix(char* haystack_start,char* needle_start)

{
char* haystack = haystack_start;
char* needle = needle_start;
while(*haystack && *needle)
{
if(*haystack++ != *needle++)
return NULL; //填空位置
}
if(*needle)
return NULL;

return haystack_start;

}

void main()

{
cout<<prefix("abc123","abc")<<endl;
}
/*
abc123
*/

#include<iostream>
using namespace std;
char* prefix(char* haystack_start, char* needle_start)
{
char* haystack = haystack_start;
char* needle = needle_start;
while(*haystack && *needle)
{
if(*haystack++ != *needle++)
return NULL; //填空位置
}
if(*needle)
return NULL;
return haystack_start;
}

void main()
{
cout<<prefix("abc123","abc")<<endl;
}
/*
abc123
*/


<6>三部排序

p++

[cpp]
view plaincopyprint?

#include<iostream>
using namespace std;
void sort3p(int* x,int len)

{
int p = 0;

int left = 0;
int right = len-1;
while(p<=right)
{
if(x[p]<0)
{
int t = x[left];
x[left] = x[p];
x[p] = t;
left++;
p++;
}
else if(x[p]>0)
{
int t = x[right];
x[right] = x[p];
x[p] = t;
right--;
}
else
{
p++; //填空位置
}
}
}

void main()
{
int x[] = {25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0};
sort3p(x,sizeof(x)/sizeof(x[0]));
for(int i = 0;i <sizeof(x)/sizeof(x[0]);i++)
cout<<x[i]<<" ";

cout<<endl;
}

/*
-3 -2 -16 -5 0 0 0 21 19 33 25 16 18 25

*/

#include<iostream>
using namespace std;
void sort3p(int* x, int len)
{
int p = 0;
int left = 0;
int right = len-1;
while(p<=right)
{
if(x[p]<0)
{
int t = x[left];
x[left] = x[p];
x[p] = t;
left++;
p++;
}
else if(x[p]>0)
{
int t = x[right];
x[right] = x[p];
x[p] = t;
right--;
}
else
{
p++; //填空位置
}
}
}

void main()
{
int x[] = {25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0};
sort3p(x,sizeof(x)/sizeof(x[0]));
for(int i = 0;i < sizeof(x)/sizeof(x[0]);i++)
cout<<x[i]<<" ";
cout<<endl;
}

/*
-3 -2 -16 -5 0 0 0 21 19 33 25 16 18 25
*/


<7>错误票据

[cpp]
view plaincopyprint?

#include<iostream>
#include<vector>
using namespace std;
void f(int N)
{
if(N == 0)
return;
vector<int> v;
int row = 0;

while(1)
{
int num;
cin>>num;
v.push_back(num);
if(cin.get() ==
'\n')
{
if(++row == N)

break;
}
}

int min = v[0],max = v[0];

for(int i = 1;i <= v.size()-1;i++)
{
if(v[i] < min)

min = v[i];
if(v[i] > max)

max = v[i];
}

int* len =
new int[max];
for(int m = 0;m < max;m++)
{
len[m] = 0;
}

for(int j = 0;j <= v.size()-1;j++)
{
len[v[j]]++;
}

for(int k = min;k <= max;k++)
{
if(len[k] == 0)
cout<<k<<" ";

if(len[k] > 1)
cout<<k<<" ";

}
}

void main()

{
int N;
cin>>N;
f(N);
cout<<endl;
}

#include<iostream>
#include<vector>
using namespace std;
void f(int N)
{
if(N == 0)
return;
vector<int> v;
int row = 0;
while(1)
{
int num;
cin>>num;
v.push_back(num);
if(cin.get() == '\n')
{
if(++row == N)
break;
}
}

int min = v[0],max = v[0];
for(int i = 1;i <= v.size()-1;i++)
{
if(v[i] < min)
min = v[i];
if(v[i] > max)
max = v[i];
}

int* len = new int[max];
for(int m = 0;m < max;m++)
{
len[m] = 0;
}

for(int j = 0;j <= v.size()-1;j++)
{
len[v[j]]++;
}

for(int k = min;k <= max;k++)
{
if(len[k] == 0)
cout<<k<<" ";
if(len[k] > 1)
cout<<k<<" ";
}
}

void main()
{
int N;
cin>>N;
f(N);
cout<<endl;
}


<8>翻硬币

[cpp]
view plaincopyprint?

#include<iostream>
using namespace std;
int f(char sorc[],char dest[])
{
int minTimes = 0;//最少翻转次数

char* p = sorc;
char* q = dest;
while(*p=='o' || *p=='*')
{
if(*p != *q)
{
switch(*p)
{
case '*':
*p = 'o';
if(*(p+1) == '*')
{
*(p+1) = 'o';
}
else
{
if(*(p+1) == 'o')
*(p+1) = '*';

}
p++;
q++;
minTimes++;
break;
case 'o':
*p = '*';
if(*(p+1) ==
'*')
{
*(p+1) = 'o';

}
else
{
if(*(p+1) ==
'o')
*(p+1) = '*';
}
p++;
q++;
minTimes++;
break;
}
}
else //设计程序,当你考虑到相等的情况,就要考虑到不等的情况
{
p++;
q++;
}
}
return minTimes;
}

void main()
{
char sroc[30];
char dest[30];

cin>>sroc>>dest;
cout<<f(sroc,dest)<<endl;
}

/*
**********
o****o****
5
*/

#include<iostream>
using namespace std;
int f(char sorc[],char dest[])
{
int minTimes = 0;   //最少翻转次数
char* p = sorc;
char* q = dest;
while(*p=='o' || *p=='*')
{
if(*p != *q)
{
switch(*p)
{
case '*':
*p = 'o';
if(*(p+1) == '*')
{
*(p+1) = 'o';
}
else
{
if(*(p+1) == 'o')
*(p+1) = '*';
}
p++;
q++;
minTimes++;
break;
case 'o':
*p = '*';
if(*(p+1) == '*')
{
*(p+1) = 'o';
}
else
{
if(*(p+1) == 'o')
*(p+1) = '*';
}
p++;
q++;
minTimes++;
break;
}
}
else             //设计程序,当你考虑到相等的情况,就要考虑到不等的情况
{
p++;
q++;
}
}
return minTimes;
}

void main()
{
char sroc[30];
char dest[30];
cin>>sroc>>dest;
cout<<f(sroc,dest)<<endl;
}

/*
**********
o****o****
5
*/


<9>带分数

[cpp]
view plaincopyprint?

#include<iostream>
#include<ctime>
using namespace std;
int N;
int c[10];
//记录1-9数字的全排列
bool vis[10]; //记录空间节点是否被访问过
int kinds = 0;

//////////////////
int GetWeiShu(int N)//得到一个指定数字的位数

{
int weishu = 0;
while(N > 0)
{
weishu++;
N /= 10;
}
return weishu;

}

/////////////////
int GetNum(int start,int end)
{
int sum = 0;

for(int i = start;i <= end;i++)
{
sum = sum*10 + c[i];
}
return sum;
}

/////////////////
void check(int N,int* c)
{
for(int i = 1;i <= GetWeiShu(N);i++)
{
int midMinLen = (9-i+1)/2;

for(int j = i+midMinLen;j <= 8;j++)
{
int X = GetNum(1,i);
int Y = GetNum(i+1,j);

int Z = GetNum(j+1,9);
if(Y%Z==0 && N==X+Y/Z)

{
//cout<<N<<"="<<X<<"+"<<Y<<"/"<<Z<<endl;

kinds++;
}
}
}

}

/////////////////
void dfs(int start,int n)
{
if(start == 10)

{
check(N,c);
return;
}

for(int i = 1;i <= n;i++)
{
if(!vis[i])

{
c[start] = i;
vis[i] = true;
dfs(start+1,n);
vis[i] = false;
}
}
}

void main()
{
double start = clock();

cin>>N;
dfs(1,9);
double end = clock();
cout<<"一共有:"<<kinds<<"种情况"<<endl;
cout<<"运行时间:"<<(end-start)/CLOCKS_PER_SEC<<"s"<<endl;

}

/*
100
100=3+69258/714
100=81+5643/297
100=81+7524/396
100=82+3546/197
100=91+5742/638
100=91+5823/647
100=91+7524/836
100=94+1578/263
100=96+1428/357
100=96+1752/438
100=96+2148/537
一共有:11种情况
运行时间:8.41s

105
105=72+6534/198
105=87+3456/192
105=87+9612/534
105=92+5681/437
105=92+6734/518
105=98+3647/521
一共有:6种情况
运行时间:3.512s
*/

#include<iostream>
#include<ctime>
using namespace std;
int N;
int c[10];      //记录1-9数字的全排列
bool vis[10];   //记录空间节点是否被访问过
int kinds = 0;
//////////////////
int GetWeiShu(int N)     //得到一个指定数字的位数
{
int weishu = 0;
while(N > 0)
{
weishu++;
N /= 10;
}
return weishu;
}

/////////////////
int GetNum(int start,int end)
{
int sum = 0;
for(int i = start;i <= end;i++)
{
sum = sum*10 + c[i];
}
return sum;
}

/////////////////
void check(int N,int* c)
{
for(int i = 1;i <= GetWeiShu(N);i++)
{
int midMinLen = (9-i+1)/2;
for(int j = i+midMinLen;j <= 8;j++)
{
int X = GetNum(1,i);
int Y = GetNum(i+1,j);
int Z = GetNum(j+1,9);
if(Y%Z==0 && N==X+Y/Z)
{
//cout<<N<<"="<<X<<"+"<<Y<<"/"<<Z<<endl;
kinds++;
}
}
}

}

/////////////////
void dfs(int start,int n)
{
if(start == 10)
{
check(N,c);
return;
}

for(int i = 1;i <= n;i++)
{
if(!vis[i])
{
c[start] = i;
vis[i] = true;
dfs(start+1,n);
vis[i] = false;
}
}
}

void main()
{
double start = clock();
cin>>N;
dfs(1,9);
double end = clock();
cout<<"一共有:"<<kinds<<"种情况"<<endl;
cout<<"运行时间:"<<(end-start)/CLOCKS_PER_SEC<<"s"<<endl;

}

/*
100
100=3+69258/714
100=81+5643/297
100=81+7524/396
100=82+3546/197
100=91+5742/638
100=91+5823/647
100=91+7524/836
100=94+1578/263
100=96+1428/357
100=96+1752/438
100=96+2148/537
一共有:11种情况
运行时间:8.41s

105
105=72+6534/198
105=87+3456/192
105=87+9612/534
105=92+5681/437
105=92+6734/518
105=98+3647/521
一共有:6种情况
运行时间:3.512s
*/


<10>连号区间数

[cpp]
view plaincopyprint?

#include<iostream>
#include<vector>
using namespace std;

vector<int> v;

int kinds = 0;

//////////////////
int GetMin(const vector<int> & v,int start,int
end)
{
int min = v[start];
for(int i = start;i <= end;i++)
{
if(v[i] < min)
min = v[i];
}
return min;

}

//////////////////
int GetMax(const vector<int> & v,int start,int
end)
{
int max = v[start];
for(int i = start;i <= end;i++)
{
if(v[i] > max)
max = v[i];
}
return max;

}

//////////////////
void f(const vector<int> & v)
{
for(int i = 0;i < v.size();i++)
for(int j = 0;j < v.size();j++)
{
int min = GetMin(v,i,j);

int max = GetMax(v,i,j);
if(j-i+1 == max-min+1)

{
kinds++;
}
}
}

void main()

{

int N;
cin>>N;
while(N--)
{
int num;
cin>>num;
v.push_back(num);
}
f(v);
cout<<kinds<<endl;
}

/*
5
3 4 2 5 1
9
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: