2015年第六届C/C++ B组省赛真题
5.九组数分组
1,2,3…9 这九个数字组成一个分数,其值恰好为1/3,如何组法?
下面的程序实现了该功能,请填写划线部分缺失的代码。
#include <stdio.h>
void test(int x[])
{
int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3];
int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8];
if(a*3==b) printf("%d / %d\n", a, b);
}
void f(int x[], int k)
{
int i,t;
if(k>=9){
test(x);
return;
}
for(i=k; i<9; i++){
{t=x[k]; x[k]=x[i]; x[i]=t;}
f(x,k+1);
_____________________________________________ // 填空处
}
}
int main()
{
int x[] = {1,2,3,4,5,6,7,8,9};
f(x,0);
return 0;
}
题解:这就是一个全排列算法:9个数字任意组合搭配(全排列算法五颗星)
t=x[k];x[k]=x[i];x[i]=t;
6.加法变乘法
我们都知道:1+2+3+ … + 49 = 1225
现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015
比如:
1+2+3+…+1011+12+…+2728+29+…+49 = 2015
就是符合要求的答案。请你寻找另外一个可能的答案,并把位置靠前的那个乘号左边的数字提交(对于示例,就是提交10)。
注意:需要你提交的是一个整数,不要填写任何多余的内容。
题解:暴力循环求解或者全排列:对乘号的不同分布进行全排列。
#include <iostream>
using namespace std;
#include <algorithm>
int main()
{
int a[49];//存放1-49数字
int b[48];//存放48个符号即加减
int i;
bool flag=true;
for(i=0;i<49;i++)
{
a[i]=i+1;
}
for(i=0;i<48;i++)
{
b[i]=1;//1代表加号
}
b[0]=b[1]=0;//0代表减号
do
{
flag=true;
for(i=0;i<48;i++)
{
if(b[i]==0&&b[i+1]==0)//判断在该排列的情况下,两个乘号是否相邻
{
flag=false;
}
}
if(flag)
{
int sum=1225;
int c[4];int j=0;int x,y;
for(i=0;i<48;i++)
{
if(b[i]==0)
{
c[j]=a[i];j++;//存放相乘的数
c[j]=a[i+1];j++;
}
}
for(j=0;j<4;j++)
{
sum-=c[j];
}
x=c[0]*c[1];
y=c[2]*c[3];
sum=sum+x+y;
if(sum==2015)
{
cout<<c[0];
cout<<c[1];
cout<<c[2];
cout<<c[3];
cout<<endl;
}
}
}while(next_permutation(b,b+48));
return 0;
}
7.牌型种数
小明被劫持到X赌城,被迫与其他3人玩牌。
一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张。
这时,小明脑子里突然冒出一个问题:
如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少种呢?
请填写该整数,不要填写任何多余的内容或说明文字。
题解:暴力:使用十三层循环,最后if语句判断
8.移动距离
X星球居民小区的楼房全是一样的,并且按矩阵样式排列。其楼房的编号为1,2,3…
当排满一行时,从下一行相邻的楼往反方向排号。
比如:当小区排号宽度为6时,开始情形如下:
1 2 3 4 5 6
12 11 10 9 8 7
13 14 15 …
我们的问题是:已知了两个楼号m和n,需要求出它们之间的最短移动距离(不能斜线方向移动)
输入为3个整数w m n,空格分开,都在1到10000范围内
w为排号宽度,m,n为待计算的楼号。
要求输出一个整数,表示m n 两楼间最短移动距离。
例如:
用户输入:
6 8 2
则,程序应该输出:
4
再例如:
用户输入:
4 7 20
则,程序应该输出:
5
题解:找出该二维矩阵数学递增的算法描述即可。
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int w,m,n;
int i,j;
cin>>w>>m>>n;
int ns;
if(m>n)
ns=m;
else
ns=n;
ns=ns/w+1;//该二维矩阵的行数
int arr[ns][w];
int k=1;
int h=w*2;
int kt,ht;
//二维矩阵赋值算法
for(i=0;i<ns;i++)
{
ht=h;kt=k;
for(j=0;j<w;j++)
{
if(i%2==0)//判断奇偶行
{
arr[i][j]=k;k++;//奇数行递增(从左往右)
}
else
{
arr[i][j]=h;h--;//偶数行递减(从左往右)
}
}
if(i%2==0)
k=kt+w*2;//下一个奇数行的开始数
if(i%2!=0)
h=ht+w*2;//下一个偶数行的开始数
}
int i1,j1,i2,j2;
for(i=0;i<ns;i++)
{
for(j=0;j<w;j++)
{
if(arr[i][j]==m)
{
i1=i;j1=j;
}
if(arr[i][j]==n)
{
i2=i;j2=j;
}
}
}
cout<<i1<<j1;
cout<<i2<<j2;
int s=abs(j2-j1)+abs(i2-i1);
cout<<s;
return 0;
}