第四届蓝桥杯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
*/
相关文章推荐
- 第四届蓝桥杯C++本科B组预赛解题报告
- 2013蓝桥杯预赛C/C++本科B组解题报告
- 第四届蓝桥杯C++本科B组决赛解题报告
- 2014年蓝桥杯预赛 C/C++本科A组 解题报告 史丰收速算
- 2013第四届 蓝桥杯c/c++B组预赛 解题报告(还在更新中。。。。。)
- 2013第四届 蓝桥杯c/c++B组预赛 解题报告
- 运行时间排列第四届蓝桥杯C++本科B组解题报告
- 2014年蓝桥杯预赛 C/C++本科B组 解题报告 史丰收速算
- 2014 第五届蓝桥杯预赛c/c++本科B组 解题报告
- 2014年蓝桥杯预赛 C/C++本科B组 解题报告 打印图形
- 2014年蓝桥杯预赛 C/C++本科B组 解题报告 (本人写的)
- 2014年第五届蓝桥杯预赛 C/C++本科B组 快速解题思路及报告(完整版,4.9修订)
- 2013年第四届蓝桥杯全国软件大赛本科A组c++预赛 题目及参考答案
- 2014蓝桥杯本科C/C++组预赛第9题<斐波那契>解题报告
- 第三届蓝桥杯C++本科B组决赛解题报告(更新中)
- 蓝桥杯试题与分析(第四届C/C++本科A组预赛)
- 第五届蓝桥杯软件大赛C/C++本科B组决赛解题报告
- 第二届蓝桥杯C++本科B组决赛解题报告
- 第五届蓝桥杯软件大赛C/C++本科B组解题报告
- 第四届蓝桥杯本科A组解题报告(和B组相同的题目详见B组解题报告)