You are on page 1of 9

实验七:一维数组与二维数组

实验目的:一维数组与二维数组熟悉和掌握一维数组和二维数组的说明、初始
化方法,数组元素访问方法熟悉和掌握一维数组和二维数组的说明、初始化方
法,数组元素访问方法

题目 1:取最大值

手动输入一个 3 行 4 列的二维数组 a,把二维数组 a 的每一行的最大元素放


到一个一维的数组中。
例如:a[3][4]={{1,2,7,8},{3,4,9,10},{5,6,11,12}},则 b[3]={8,10,12}
#include <iostream>
using namespace std;
int max(int a, int b) //定义 max 函数,用于返回两数之间最大值(给 mymax 函数用)
{
return a > b ? a : b;
}
int mymax(int a, int b, int c, int d) //定义 mymax 函数,用于返回四数之间最大值
{
return max(max(max(a, b), c), d);
}
int main()
{
int a[3][4], b[3]; //定义数组
for (int i = 0; i < 3; i++) //定义循环用于遍历数组 a 的行
{
for (int j = 0; j < 4; j++) //定义循环用于遍历数组 a 的列
{
cin >> a[i][j]; //用 cin 来输入数据到数组 a 的指定元素
}
b[i] = mymax(a[i][0], a[i][1], a[i][2], a[i][3]); //求该行中最大值存储到 b[i]
}
for (int k = 0;k < 3;k++)
cout << b[k] << endl;
return 0;
}

题目 2:循环左移

将一个数组中的数循环左移 n 位。
例如,如果数组中原来的数为:1 2 3 4 5
移动 1 位后变成:2 3 4 5 1
移动 2 位后变成:3 5 5 1 2
#include <iostream>
using namespace std;
void reverse(int *arr , int begin , int end) //逆置
{
int i , j;
for(i = begin , j = end ; i < j ; i++ , j--)
{
int t;
t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
void function(int *arr , int n , int p) //循环左移
{
reverse(arr,0,p-1);
reverse(arr,p,n-1);
reverse(arr,0,n-1);
}
void display(int *arr , int n)
{
int i;
for(i = 0 ; i < n ; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
int main()
{
int arr_len,arr[100],i,j;
cin >> arr_len;
for (i = 0;i < arr_len;i++)
cin >> arr[i];
//int arr[5] = {1,2,3,4,5};
cin >> j;
function(arr,arr_len,j);
display(arr,arr_len);
return 0;
}

题目 3:凯撒加密算法

凯撒加密算法是古罗马凯撒大帝用来对军事情报进行加密的算法,它采用了替换方法对信
息中的每一个英文字符循环替换为字母表序列该字符后面第三个字符,对应关系如下:
明码字母表:ABCDEFGHIJKLMNOPQRSTUVWXYZ
密码字母表:DEFGHIJKLMNOPQRSTUVWXYZABC
明码字母表:abcdefghijklmnopqrstuvwxyz
密码字母表:defghijklmnopqrstuvwxyzabc

这个例子中位移量为 3;

明码字符 P,其密码字符 C 满足如下条件(n 为位移量):


C=(P+n)mod26
解密方法反之,满足:
P=(C–n)mod26
Input:第一行:1 为加密,2 为解密,输入的第一行为选择是加密模式还是解密模式
第二行:字符串
第三行:位移量
Output:输入为字符串经过位移量的位移后得到的加密或解密结果

#include<iostream>
#include<string.h>
#define N 100
using namespace std;
//凯撒密码
//加密公式 f(a)=(a+3) mod 26
//解密公式 f(a)=(a+23) mod 26
int psw(char *strI, int numB) //加密过程
{
for (int i = 0; i < strlen(strI); i++)
{
if ((!(strI[i] >= 'A' && strI[i] <= 'Z')) && (!(strI[i] >= 'a' && strI[i] <= 'z')))
{
cout << "输入字符串中存在非法字符!";
return 0;

}
}
for (int i = 0; i < strlen(strI); i++)
{
if (strI[i] >= 'A' && strI[i] <= 'Z')
{
strI[i] = ((strI[i] - 'A') + numB) % 26 + 'A';
}
else if (strI[i] >= 'a' && strI[i] <= 'z')
{
strI[i] = ((strI[i] - 'a') + numB) % 26 + 'a';
}

}
cout << "加密完成:" << strI << endl;
return 0;
}
int unpsw(char *strI, int numB) //解密
{

int num;
num = 26 - numB;
for (int i = 0; i < strlen(strI); i++)
{
if ((!(strI[i] >= 'A' && strI[i] <= 'Z')) && (!(strI[i] >= 'a' && strI[i] <= 'z')))
{
cout << "输入字符串中存在非法字符!";
return 0;

}
}
for (int i = 0; i<strlen(strI); i++)
{

if (strI[i] >= 'A' && strI[i] <= 'Z')


{
strI[i] = ((strI[i] - 'A') + num) % 26 + 'A';
}
else if (strI[i] >= 'a' && strI[i] <= 'z')
{
strI[i] = ((strI[i] - 'a') + num) % 26 + 'a';
}

}
cout << "解密完成:" << strI << endl;
return 0;
}
int main()
{
char str[N];
int model;
int numB;
cin >> model;
switch(model)
{
case 1: cin>>str;
cin>>numB;
psw(str,numB);
cout<<endl;
break;
case 2: cin>>str;
cin>>numB;
unpsw(str,numB);
cout<<endl;
break;
default:cout << "此程序不提供此项功能!" << endl;
}
return 0;
}

题目 4:数组合并

把有序(从小到大排列)的数组 a 和数组 b 合并,要求合并后的数组依然有序。


#include <iostream>
using namespace std;
int main()
{
int a[100], b[100],c[201],a_len,b_len,i,j,k,m,n,c_len;
cin >> a_len;
for(i = 0;i < a_len;i++)
cin >> a[i];
cin >> b_len;
for (j = 0;j < b_len;j++)
cin >> b[j];
/*int a[M]={1,2,5,7,9};
int b[N]={2,4,6};
int c[M+N]; */
int ai=0,bj=0,ck=0; //三个标识位,分别记录三个数组的下标
while(ai<a_len&&bj<b_len) //a 数组和 b 数组都没有到达末尾时
{
if(a[ai]<b[bj])
c[ck++]=a[ai++];
else
c[ck++]=b[bj++];
}
if(ai==a_len) //若 a 数组已经到达末尾,直接把 b 数组剩余元素拷贝到 c 数组即可
{
while(bj<b_len)
c[ck++]=b[bj++];
}
if(bj==b_len) //若 b 数组已经到达末尾,直接把数组剩余元素拷贝到 c 数组即可
{
while(ai<a_len)
c[ck++]=a[ai++];
}
c_len = a_len + b_len;
for (k = 0;k <c_len-1;k++) //遍历 c 数组
{
if (c[k] == c[k + 1])
{
for (m = k;m < c_len;m++)
c[m] = c[m + 1];
c_len = c_len - 1;
}

}
for (n = 0;n < c_len;n++) //遍历 c 数组
cout << c[n] << endl;
return 0;
}

题目 5:背包问题

为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设
你一共有资金 n 元,而市场有 m 种大米,每种大米都是袋装产品,其价格不等,并且只能
整袋购买。
请问:你用有限的资金最多能采购多少公斤粮食呢?

Input
输入数据第一行是两个整数 n 和 m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的
种类,然后是 m 行数据,每行包含 3 个数 p,h 和 c(1<=p<=20,1<=h<=200,1<=c<=20),分别
表示每袋的价格、每袋的重量以及对应种类大米的袋数。

Output
对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,
并且经费你可以不用完。每个实例的输出占一行。

输入:
8 2
2 100 4
4 100 2

输出:
400

#include<math.h>
#include<iostream>
using namespace std;
int f[105], V;

inline int max(int a, int b)


{
return a>b ? a : b;
}

void ZeroOnePack(int cost, int weight) //01 背包


{
int v;
for (v = V;v >= cost;v--)
f[v] = max(f[v - cost] + weight, f[v]);
}

void CompletePack(int cost, int weight) //完全背包


{
int v;
for (v = cost;v <= V;v++)
f[v] = max(f[v - cost] + weight, f[v]);
}

void MultipelePack(int cost, int weight, int amount) //多重背包


{
int k, num;
if (cost*amount >= V)
{
CompletePack(cost, weight);
return;
}
for (k = 1;k<amount;k *= 2)
{
ZeroOnePack(k*cost, k*weight);
amount = amount - k;
}
ZeroOnePack(amount*cost, amount*weight);
}

int main()
{
int t, i, n, cost, weight, amount;
//memset(f, 0, sizeof(f));
cin >> V >> n;
for (i = 1;i <= n;i++)
{
cin >> cost >> weight >> amount;
MultipelePack(cost, weight, amount);
}
cout << f[V] << endl;
return 0;
}

有 N 种物品和一个容量为 V 的背包。第 i 种物品最多有 n[i]件可用,每件费用是 c[i],价值


是 w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和
最大。

You might also like