Online Judge地址:http://boj.me/onlinejudge/index.php。由于系统上的题目已经看不到了,下面的题目描述都来自网上的回忆版,但源代码是可以被Accpted
的。
ACM—BOJ—2010年北邮计算机学院研究生入学考试(复试)上机测试——即1814(A比较奇偶数个数)、1815(B找最小数)、1816(C翻转)、1817(D哈夫曼树)
A题:
题目大意(回忆版):第一行输入一个数,为n,第二行输入n个数,这n个数中,如果偶数比奇数多,输出NO,否则输出YES。
Sample:
Input:
5
1 2 3 4 5
Output:
YES
源代码:
#include<stdio.h>
#define N 500
int main()
{
int n;
int odd=0,even=0;
int m;
int i;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&m);
if(m%2==0)
even++;
else
odd++;
}
if(even>odd)
printf("NO\n");
else
printf("YES\n");
return 0;
}
B题:
题目大意(回忆版):第一行输入一个数n,1 <= n <= 1000,下面输入n行数据,每一行有两个数,分别是x y。输出一组x y,该组数据是所有数据中x最小,且在x相等的情况下y最小的。
Sample:
Input:
5
3 3
2 2
5 5
2 1
3 6
Output:
2 1
源代码:
#include<stdio.h>
typedef struct LNode
{
int x;
int y;
};
int main()
{
int n;
int x_min =10000,y_min =10000;
int i,j;
struct LNode a[1000];
scanf("%d",&n);
for(j=0;j<n;j++)
scanf("%d%d",&a[j].x,&a[j].y);
for(i=0;i<n;i++)
{
if(a[i].x<x_min)
{
x_min = a[i].x;
y_min = a[i].y;
}
else if(a[i].x == x_min)
{
if(a[i].y<y_min)
y_min = a[i].y;
}
}
printf("%d %d\n",x_min,y_min);
return 0;
}
C题:
题目大意(回忆版):该题是要翻转数据。首先输入一个5 * 5的数组,然后输入一行,这一行有四个数,前两个代表操作类型,后两个数x y代表需操作数据为以x y为左上角的那几个数据。
操作类型有四种:
1 2 表示:90度,顺时针,翻转4个数
1 3 表示:90度,顺时针,翻转9个数
2 2 表示:90度,逆时针,翻转4个数
2 3 表示:90度,逆时针,翻转9个数
Sample:
Input:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
1 3 1 1
Output:
11 6 1 4 5
12 7 2 9 10
13 8 3 14 15
16 17 18 19 20
21 22 23 24 25
源代码:
#include<stdio.h>
int main()
{
int a[5][5];
int pa,pb,x,y;
int i=0,j=0,temp=0,temp2;
for(i=0;i<5;i++)
for(j=0;j<5;j++)
scanf("%d",&a[i][j]);
scanf("%d%d%d%d",&pa,&pb,&x,&y);
if(pa==1 && pb==2)
{
temp = a[x-1][y-1];
a[x-1][y-1] = a[x][y-1];
a[x][y-1] = a[x][y];
a[x][y] = a[x-1][y];
a[x-1][y] = temp;
}
else if(pa==1 && pb==3)
{
temp = a[x-1][y-1];
temp2 = a[x][y-1];
a[x-1][y-1] = a[x+1][y-1];
a[x][y-1] = a[x+1][y];
a[x+1][y-1] = a[x+1][y+1];
a[x+1][y] = a[x][y+1];
a[x+1][y+1] = a[x-1][y+1];
a[x][y+1] = a[x-1][y];
a[x-1][y+1] = temp;
a[x-1][y] = temp2;
}
else if(pa==2 && pb==2)
{
temp = a[x-1][y-1];
a[x-1][y-1] = a[x-1][y];
a[x-1][y] = a[x][y];
a[x][y] = a[x][y-1];
a[x][y-1] = temp;
}
else if(pa==2 && pb==3)
{
temp = a[x-1][y-1];
temp2 = a[x][y-1];
a[x-1][y-1] = a[x-1][y+1];
a[x][y-1] = a[x-1][y];
a[x-1][y+1] = a[x+1][y+1];
a[x-1][y] = a[x][y+1];
a[x+1][y+1] = a[x+1][y-1];
a[x][y+1] = a[x+1][y];
a[x+1][y-1] = temp;
a[x+1][y] = temp2;
}
for(i=0;i<5;i++)
{
for(j=0;j<4;j++)
printf("%d ",a[i][j]);
printf("%d",a[i][4]);
printf("\n");
}
return 0;
}
D题:
题目大意(回忆版):哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。Sample:
Input:
5
1 2 2 5 9
Output:
37
解释:即生成如下图哈夫曼树,结点1的权值为4,结点2的权值为4,结点2的权值为3,结点5的权值为2,结点9的权值为1,和为37
源代码(非原创):
#include <stdio.h>
// 结点的数据结构
typedef struct HNode
{
unsigned int weight; // 权值
unsigned int parent; // 父结点
};
void Select( HNode* m_Node, int m_Cycle )
{
// 循环数
int temp;
// 记录下最小的两个数的位置
int m_FirstMin_Pos = -1, m_SecondMin_Pos = -1;
// 最小的两个数,初始赋值为题目所给最大值加 1
int m_FirstMin = 1001, m_SecondMin = 1001;
for( temp = 0; temp <= m_Cycle ; ++ temp )
{
if ( m_Node[ temp ].parent == 0 )
{
// 如果结点权值比 m_FirstMin 还小,
// 记录该结点位置
if( m_Node[ temp ].weight < m_FirstMin )
{
m_SecondMin = m_FirstMin;
m_SecondMin_Pos = m_FirstMin_Pos;
m_FirstMin = m_Node[ temp ].weight;
m_FirstMin_Pos = temp;
}
else
{
if( m_Node[ temp ].weight < m_SecondMin )
{
m_SecondMin = m_Node[ temp ].weight;
m_SecondMin_Pos = temp;
}
}
}
}
// 在 m_Cycle + 1 的位置为最小的两个结点的和生成的结点
m_Node[ ++ m_Cycle ].weight = m_FirstMin + m_SecondMin;
// 两个最小值结点的 parent 赋值
m_Node[ m_FirstMin_Pos ].parent = m_Cycle;
m_Node[ m_SecondMin_Pos ].parent = m_Cycle;
}
int main()
{
// 叶结点的数目
int m_Num_Count, m_Num_Count_Temp = 0;
scanf( "%d", &m_Num_Count );
// 最后形成的哈夫曼树总结点个数,为叶子结点个数 * 2 - 1
int m_TotalNode_Count = 2 * m_Num_Count - 1;
// 存哈夫曼树的数组
HNode m_Node[ 2 * m_Num_Count - 1 ];
// 临时输入数
int m_TempInput;
// 循环输入叶结点
while ( m_Num_Count_Temp < m_Num_Count )
{
scanf( "%d", &m_TempInput );
getchar();
// 放入到数组
m_Node[ m_Num_Count_Temp ].weight = m_TempInput;
m_Node[ m_Num_Count_Temp ].parent = 0;
++ m_Num_Count_Temp;
}
// 循环数
int m_Cycle;
// 对后 m_Num_Count - 1 个结点初始化
for( m_Cycle = m_Num_Count; m_Cycle < m_TotalNode_Count; ++ m_Cycle )
{
m_Node[ m_Cycle ].weight = 0;
m_Node[ m_Cycle ].parent = 0;
}
for( m_Cycle = ( m_Num_Count - 1 ); m_Cycle < ( m_TotalNode_Count - 1 ); ++ m_Cycle )
{
// 并在数组最后存放这两个结点形成的父结点
Select( m_Node, m_Cycle );
}
// 结果,输出值
int m_ResultValue = 0;
// 临时结点
HNode m_Node_Temp;
// 结点在哈夫曼树中的长度
int m_Length;
for( m_Cycle = 0; m_Cycle < m_Num_Count; ++ m_Cycle )
{
// 长度置 0
m_Length = 0;
// 临时变量
m_Node_Temp = m_Node[ m_Cycle ];
// 找 parent 直至 parent 不为 0 ,同时计算长度
while( m_Node_Temp.parent != 0 )
{
m_Node_Temp = m_Node[ m_Node_Temp.parent ];
++ m_Length;
}
// 计算该结点的权值 * 长度,加到总输出值中
m_ResultValue += ( m_Node[ m_Cycle ].weight *m_Length );
}
// 输出
printf( "%d\n", m_ResultValue );
return 0;
}