7-7 矩阵A乘以B 给定两个矩阵A和B,要求你计算它们的乘积矩阵AB。需要注意的是,只有规模匹配的矩阵才可以相乘。即若A有Ra行、Ca列,B有Rb行、Cb列,则只有Ca与Rb相等时,两个矩阵才能相乘。 输入格式:输入先后给出两个矩阵A和B。对于每个矩阵,首先在一行中给出其行数R和列数C,随后R行,每行给出C个整数,以1个空格分隔,且行首尾没有多余的空格。输入保证两个矩阵的R和C都是正数,并且所有整数的绝对值不超过100。 输出格式:若输入的两个矩阵的规模是匹配的,则按照输入的格式输出乘积矩阵AB,否则输出 输入样例1:
输出样例1:
输入样例2:
输出样例2:
#include<bits/stdc .h> using namespace std; int main() { int r1,c1,r2,c2; cin>>r1>>c1; int s[r1 5][c1 5]; for(int i=0;i<r1;i ) { for(int j=0;j<c1;j ) { cin>>s[i][j]; } } cin>>r2>>c2; int b[r2 5][c2 5]; for(int i=0;i<r2;i ) { for(int j=0;j<c2;j ) { cin>>b[i][j]; } } int w[r1 5][c2 5]; if(c1!=r2)cout<<"Error: "<<c1<<" != "<<r2<<endl; else if(c1==r2) { int q=0; while(q<r1){ int num=0;//q<r1 for(int i=0;i<c2;i ) { w[r1 5][c2 5]={0},num=0; for(int j=0;j<c1;j ) { num =s[q][j]*b[j][i]; } w[q][i]=num; } q ; } cout<<r1<<" "<<c2<<endl; for(int i=0;i<r1;i ) { for(int j=0;j<c2;j ) { if(j==0)cout<<w[i][j]; else cout<<" "<<w[i][j]; } cout<<endl; } } }
7-1阅览室 天梯图书阅览室请你编写一个简单的图书借阅统计程序。当读者借书时,管理员输入书号并按下 注意:由于线路偶尔会有故障,可能出现不完整的纪录,即只有 输入格式:输入在第一行给出一个正整数N(≤),随后给出N天的纪录。每天的纪录由若干次借阅操作组成,每次操作占一行,格式为:
每一天的纪录保证按时间递增的顺序给出。 输出格式:对每天的纪录,在一行中输出当天的读者借书次数和平均阅读时间(以分钟为单位的精确到个位的整数时间)。 输入样例:
输出样例:
题解:用一个初始化为0的数组来标记此书号是否被借以及归还的情况,为S时记为1,为E时再记为0,并记录总时间,书号为0时退出。答案要四舍五入 #include<bits/stdc .h> using namespace std; int main() { int n; cin>>n; int s[1010]={0},w[1010]={0};//分别记录书号借还情况、及借走的时间 while(n--) { int b,hh,mm,ct=0; char ch; double sum=0;//***/类型 while(scanf("%d %c %d:%d",&b,&ch,&hh,&mm)&&b!=0) { if(ch=='S') { w[b]=hh*60 mm;//将时间转换为分钟 s[b]=1; // cout<<"w[b] "<<w[b]<<endl; } else if(ch=='E'&&s[b]==1) { sum =hh*60 mm-w[b];//还书时减去原来的时间 // cout<<"sun "<<sum<<endl; s[b]=0; ct ;//记录次数 } } if(ct==0)cout<<"0 0"<<endl; else { printf("%d %.0lf\n",ct,sum*1.0/ct);//答案四舍五入 } } } 7-11 集合相似度 给定两个整数集合,它们的相似度定义为:/。其中Nc是两个集合都有的不相等整数的个数,Nt是两个集合一共有的不相等整数的个数。你的任务就是计算任意一对给定集合的相似度。 输入格式:输入第一行给出一个正整数N(≤),是集合的个数。随后N行,每行对应一个集合。每个集合首先给出一个正整数M(≤),是集合中元素的个数;然后跟M个[区间内的整数。 之后一行给出一个正整数K(≤),随后K行,每行对应一对需要计算相似度的集合的编号(集合从1到N编号)。数字间以空格分隔。 输出格式:对每一对需要计算的集合,在一行中输出它们的相似度,为保留小数点后2位的百分比数字。 输入样例:
输出样例:
运用set函数以及里面的find函数,在集合里挨个查找某个数,如果在集合s里查找x,就是s.find(x),如果找到就返回该数的位置,找不到就返回s.end()。 #include<bits/stdc .h> using namespace std; int main() { int n; cin>>n; set<int>s[51]; for(int i=1;i<=n;i ) { int m; cin>>m; long long p; while(m--) { scanf("%lld",&p); s[i].insert(p); } } int k; cin>>k; while(k--) { int a,b; cin>>a>>b; int ct=0; set<int>::iterator it; for(it = s[a].begin(); it != s[a].end(); it ) { if(s[b].find(*it)!=s[b].end())ct ;//两集合中都有的值的数量 } int sum=s[a].size() s[b].size()-ct; double num; num=ct*1.00/sum*100; printf("%.2lf",num); cout<<"%"<<endl; } } /************/ 7-9 树的遍历 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。 输入格式:输入第一行给出一个正整数N(≤),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。 输出格式:在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。 输入样例:
输出样例:
#include<stdio.h> #include<malloc.h> int N = 0; int PreOrder[33] = { '\0' };//中序遍历 int PostOrder[33] = { '\0' };//后序遍历 typedef struct node { int num; struct node* left;//左子树 struct node* right;//右子树 }node; struct node *create(int pos[], int pre[], int n); void sequence(node *T);//层序排序输出 int main(void) { node *T = NULL;//构建二叉树 scanf("%d", &N); int i = 0; for (i = 0; i < N; i ) scanf("%d", &PostOrder[i]); for (i = 0; i < N; i ) scanf("%d", &PreOrder[i]); T = create(PostOrder, PreOrder, N); sequence(T); return 0; } void sequence(node *T) { struct node *p[33], *q; int f = 0, r = 0; int num = 0; if (T) { p[r ] = T;//根节点入队列 while (f != r) {//队头不等于队尾时 q = p[f ];//出队 printf("%d", q->num); num ;//计数输出空格 if (num < N) printf(" "); if (q->left)//左子树不为空,入队 p[r ] = q->left; if (q->right)//右子树不为空,入队 p[r ] = q->right; } } } struct node *create(int pos[], int pre[], int n) { int i = 0, k = 0, root = 0; if (n == 0) return NULL; struct node *T; T = (struct node *)malloc(sizeof(struct node)); if (T == NULL)//分配结点内存及判断是否成功 return NULL; root = pos[n - 1];//根节点就是后序遍历的最后一位 T->num = root; for (i = 0; i<n; i ){ if (pre[i] == root){ //通过中序遍历,确定左右子树的长度 k = i; break; } } T->left = create(pos, pre, k);//递归左右子树 T->right = create(pos k, pre k 1, n - k - 1); return T; }View Code
7-10 关于堆的判断 将一系列给定数字顺序插入一个初始为空的小顶堆
输入格式:每组测试第1行包含2个正整数 输出格式:对输入的每个命题,如果其为真,则在一行中输出 输入样例:
输出样例:
堆的特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆),建造堆时进行一种自下而上的比较搜索,每当我们往堆里面插入元素的时候 , 我们总是通过改点 , 将其父节点进行向上搜索比较 , 当建造最小堆时 , 如果在该点自树的根的这条路上有节点比该值大 , 我们就将其往下移动 , 直到满足最小堆。 #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <functional> using namespace std; vector<int> v; int Find(int a) {//查找对应元素值的下标 return find(v.begin() 1, v.end(), a)-v.begin(); } int main(int argc, char const *argv[]) { int n, m, a, b; v.push_back(0);//0坐标用掉,这样比较方便 //父亲结点就是i / 2 儿子结点2 * i or 2 * i 1 char s[100], tmp[4]; scanf("%d %d", &n, &m); for(int i = 0; i < n; i) { scanf("%d", &a); v.push_back(a); push_heap(v.begin() 1, v.end(), greater<int>());//对加入的元素构造最小堆 } scanf("%*c"); while(m--) { gets(s); if(s[strlen(s) - 1] == 't') { sscanf(s, "%d", &a);//提取字符串里面的数字 if(v[1] == a) printf("T\n");//如果是根结点 else printf("F\n"); } else if(s[strlen(s) - 1] == 's') { sscanf(s, "%d %*s %d", &a, &b); a = Find(a); b = Find(b); if(a/2 == b/2) printf("T\n");//兄弟结点 else printf("F\n"); } else { sscanf(s, "%d %*s %s %*s %*s %d", &a, tmp, &b); a = Find(a); b = Find(b); if(!strcmp(tmp, "the")) { if(a == b/2) printf("T\n");//a是b的父亲结点 else printf("F\n"); } else { if(a/2 == b) printf("T\n");//a是b的儿子结点 else printf("F\n"); } } } return 0; } 来源:https://www./content-4-760051.html |
|