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

2013华为第五届编程大赛 成都初赛题目和解答

2014-04-17 15:00 471 查看
昨天看到今年的报名,把隔壁zy同学的去年题目拿过来做了一下,http://blog.csdn.net/zy416548283/article/details/23712151

前两个解法差不多,第三个用dfs,bfs方法可参考zy同学

1、路灯统计:

    题目描述

某省会城市街道纵横交错,为了监控路灯的运行状况,每条街道使用一个数字字符串标识该街道上所有路灯的运行状况。

假设路灯只有如下3种状态(分别用数字0, 1, 2标识,一盏路灯只对应其中一种状态):

0 标识路灯熄灭;

1 标识路灯开启;

2 标识路灯故障;

请根据输入的字符串,找出该街道上连续的处于相同状态的路灯的最大个数。若两种状态的路灯数量相同,则返回最先出现的路灯状态。

   输入:

街道上连续的路灯组成的状态字符串。字符串中只包含数字,每个路灯的状态为0,1,2中的一种状态。如“1101”代表4盏路灯,第3盏路灯为熄灭状态,其它3盏为开启状态。

   输出:

连续为相同状态的路灯的最大数量,上述路灯的状态;

要求:先输出数量,再输出状态,两个整数间采用一个空格间隔。如输出:53 2

样例输入

112200111

样例输出

3 1

#include<stdio.h>
#include<string.h>

#define MAX_LINE 1024

int main()
{
char str[MAX_LINE], result;
int i, max_len = -1, cur_len = 1;

fgets(str, MAX_LINE, stdin);

for (i = 0; str[i] != '\n'; i++)
{
if (str[i] == str[i+1])
cur_len++;
else {
if (cur_len > max_len) {
max_len = cur_len;
cur_len = 1;
result = str[i];
}
else if (cur_len == max_len)
cur_len = 1;
}
}
printf("%d %c", max_len, result);

return 0;
}


2. 求复数的平均值

    题目描述  由实部和虚部组成,形如(a,bi)这样的数,称为复数。

    通信系统中,通常用32bit数来表示复数(高16bit表示实部,低16bit表示虚部),如整数524295(16进制为0x00080007)

所代表的复数,实部为0x0008,虚部为0x0007。  有别于实数运算,复数加、减、乘、除运算定义如下: 

复数加公式:(a,bi) + (c,di) = (a + c),(b + d)i 复数减公式:(a,bi) + (c,di) = (a - c),(b - d)i  

复数乘公式:(a,bi) * (c,di) = (ac - bd),(ad + bc)i 复数除公式:(a,bi) / N = (a/N),(b/N)i  

题目要求,输入N个复数,计算这个N个复数的平均值,

复数Avg = (复数1*复数2 + 复数3*复数4 + … + 复数N-1*复数N) / N。 

 复数加、复数减、复数乘、复数除的结果仍然为复数,实部和虚部均为16bit有符号数,

计算过程中,当结果大于32767(0x7fff)时,输出32767;当计算结果小于-32768(0x8000)时,输出-32768。 

 输入  输入共计两行   有别于实数运算,复数加减乘除运算定义如下第一行包含1个整数,表示输入复数个数N(N为偶数,N不大于1000)   第一行包含1个整数,

表示输入复数个数N(N为偶数,N不大于1000)  输出  经计算得到的复数的平均值。 

 

样例输入  4  262149,393223,524297,655371 

样例输出  -458693

#include<stdio.h>

#define MAX_NUM 1024

typedef struct complx{
int real;
int img;
}complx;
complx comp_set[MAX_NUM];

int crossover(int m)
{
if (m > 32767)
return 32767;
else if (m < -32768)
return -32768;
else
return m;
}

complx convert(int m)
{
complx c_tmp;
c_tmp.real = (m & 0xffff0000) >> 16;
c_tmp.img =  m & 0x0000ffff;
return c_tmp;
}

int re_convert(complx a)
{
return ((a.real << 16) + a.img);
}

complx times(complx a, complx b)
{
complx tmp;
tmp.real = crossover(crossover(a.real*b.real) - crossover(a.img*b.img));
tmp.img = crossover(crossover(a.real*b.img) + crossover(a.img*b.real));
return tmp;
}

complx plus(complx a, complx b)
{
complx tmp;
tmp.real = crossover(a.real + b.real);
tmp.img = crossover(a.img + b.img);
return tmp;
}

complx div(complx a, int n)
{
complx tmp;
tmp.real = a.real / n;
tmp.img = a.img / n;
return tmp;
}

int main()
{
int n, i, i_tmp;
complx sum = {0,0}, com_tmp;

scanf("%d", &n);

if (n % 2 != 0)
return 0;

for(i = 0; i < n; i++)
{
scanf("%d", &i_tmp);
comp_set[i] = convert(i_tmp);
}

for (i = 0; i < n; i += 2)
{
com_tmp = times(comp_set[i], comp_set[i+1]);
sum = plus(sum, com_tmp);
}

sum = div(sum, n);
printf("%d", re_convert(sum));
return 0;
}


3. 连连看游戏:

题目描述

连连看,你不会?那就out了!

给定一个连连看棋盘,棋盘上每个点有各种图案(用非0数字表示),输入棋盘上的任意两个坐标,判断这两个坐标对应的图案是否可以消除,消除的条件是图案相同且图案间连线的转角数不得超过2 。

1    3    3    4

0    6    0    0

4    0    2    1

6    0    4    2

图中,(0,1)和(0,2)中的3没有转角可以消去,(1,1)和(3,0)中的6有一个转角可以消去,(2,0)和(3,2)中的4有两个转角可以消去,而(0,0)和(2,3)中的1不能消去。

输入

输入为连续的整数,第1个数为棋盘行数m,第2个数为棋盘列数n,然后依次是m*n个棋盘数据(先行后列),最后,是两个坐标对应的行号和列号,m行n列的棋盘,共计输入m*n+6个数。

输出

如果图案不能消除,输出0;如果图案可以消除,输出消除路线上图案个数(包含输入的两个图案,不考虑有多条可消除路径的情况)。

样例输入

4 4 1 3 3 4 0 6 0 0 4 0 2 1 6 0 4 2 2 0 3 2

样例输出

4

//2013 HuaWei 3 simon xia 2014.4.17
#include<stdio.h>
#include<string.h>

#define MAX_ROW 50
#define MAX_COL 50

#define UP 1
#define RIGHT 2
#define DOWN 3
#define LEFT 4

typedef struct {
int row;
int col;
int direction[5];
}position;

typedef struct {
int pathlen;
int direction;
int dir_cha_cnt;
}pathinfo;

position stack_pos[16];
pathinfo stack_info[16];

int top_pos = -1;
int top_info = -1;
int matrix[MAX_ROW][MAX_COL];

void push_pos(position pos)
{
stack_pos[++top_pos] = pos;
}

void push_info(pathinfo info)
{
stack_info[++top_info] = info;
}

position pop_pos()
{
return stack_pos[top_pos--];
}

pathinfo pop_info()
{
return stack_info[top_info--];
}

int set_dir(int row, int col, int dir[], int m, int n, int cur_dir)
{
if (!matrix[row][col+1] && col+1 < n && cur_dir != LEFT) dir[RIGHT] = 1;
if (!matrix[row][col-1] && col-1 >= 0 && cur_dir != RIGHT) dir[LEFT] = 1;
if (!matrix[row-1][col] && row-1 >= 0 && cur_dir != DOWN) dir[UP] = 1;
if (!matrix[row+1][col] && row+1 < m && cur_dir != UP) dir[DOWN] = 1;
}

int count_path(int dir[])
{
int count = 0, i = 0;
for (; i < 5; i++)
count += dir[i];
return count;
}

int get_end(int i, int j, int end, int start_row, int start_col)
{
if ( (matrix[i][j+1] == end && i != start_row && j+1 != start_col)
|| (matrix[i][j-1] == end && i != start_row && j-1 != start_col)
|| (matrix[i-1][j] == end && i-1 != start_row && j != start_col)
|| (matrix[i+1][j] == end && i+1 != start_row && j != start_col))
return 1;
else
return 0;
}

int main()
{
freopen("input_h3", "r", stdin);
int m, n, i, j, k, pathlen = 1, pathnum;
int dir_change = 0, cur_dir = 0;
int dir_tmp[5] = {0};
position a, b, pos_tmp;
pathinfo info_tmp;

memset(matrix, 0, sizeof(matrix));
scanf("%d%d", &m, &n);
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &matrix[i][j]);
scanf("%d%d%d%d", &a.row, &a.col, &b.row, &b.col);

if (matrix[b.row][b.col] != matrix[a.row][a.col] || matrix[a.row][a.col] == 0 || matrix[b.row][b.col] == 0)
return 0;

for (i = a.row, j = a.col; (!get_end(i,j,matrix[b.row][b.col],a.row,a.col)); )
{
if (!count_path(dir_tmp))
set_dir(i, j, dir_tmp, m, n, cur_dir);
pathnum = count_path(dir_tmp);

if (!pathnum) {
if (top_pos == -1) {
printf("%d", 0);
return 0;
}
else {
pos_tmp = pop_pos();
i = pos_tmp.row;
j = pos_tmp.col;
memcpy(dir_tmp, pos_tmp.direction, 5*sizeof(int));

info_tmp = pop_info();
pathlen = info_tmp.pathlen;
cur_dir = info_tmp.direction;
dir_change = info_tmp.dir_cha_cnt;
}
}else if (pathnum == 1) {
for (k = 1; k < 5; k++)
if (dir_tmp[k]) break;
if (k != cur_dir)
dir_change++;
switch (k) {
case 1:{i--; break;}
case 2:{j++; break;}
case 3:{i++; break;}
case 4:{j--; break;}
}
pathlen++;
memset(dir_tmp, 0, sizeof(dir_tmp));
}
else
{
pos_tmp.row = i;
pos_tmp.col = j;
for (k = 1; k < 5; k++)
if (dir_tmp[k]) break;
dir_tmp[k] = 0;
memcpy(pos_tmp.direction, dir_tmp, 5*sizeof(int));
push_pos(pos_tmp);

info_tmp.pathlen = pathlen;
info_tmp.direction = cur_dir;
info_tmp.dir_cha_cnt = dir_change;
push_info(info_tmp);

if (k != cur_dir)
dir_change++;
cur_dir = k;
switch (k) {
case 1:{i--; break;}
case 2:{j++; break;}
case 3:{i++; break;}
case 4:{j--; break;}
}
pathlen++;
memset(dir_tmp, 0, sizeof(dir_tmp));
}

if (dir_change > 3 && top_pos != -1) //第一次初始化0
{
pos_tmp = pop_pos();
i = pos_tmp.row;
j = pos_tmp.col;

info_tmp = pop_info();
pathlen = info_tmp.pathlen;
cur_dir = info_tmp.direction;
dir_change = info_tmp.dir_cha_cnt;
}
}
printf("%d\n", ++pathlen);
return 0;
}

边写边改,代码有点乱,跑出结果就没有改了。。。上述代码中2个栈可以合为一个
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  华为编程赛 c