codeup6.1小节——C++标准模板库(STL)介绍->vector的常见用法详解

问题 A: Course List for Student (25)

时间限制: 1 Sec  内存限制: 32 MB
提交: 676  解决: 194
[提交][状态][讨论版][命题人:外部导入]

题目描述

Zhejiang University has 40000 students and provides 2500 courses. Now given the student name lists of all the courses, you are supposed to output the registered course list for each student who comes for a query.

输入

Each input file contains one test case. For each case, the first line contains 2 positive integers: N (<=40000), the number of students who look for their course lists, and K (<=2500), the total number of courses. Then the student name lists are given for the courses (numbered from 1 to K) in the following format: for each course i, first the course index i and the number of registered students Ni (<= 200) are given in a line. Then in the next line, Ni student names are given. A student name consists of 3 capital English letters plus a one-digit number. Finally the last line contains the N names of students who come for a query. All the names and numbers in a line are separated by a space.

输出

For each test case, print your results in N lines. Each line corresponds to one student, in the following format: first print the student's name, then the total number of registered courses of that student, and finally the indices of the courses in increasing order. The query results must be printed in the same order as input. All the data in a line must be separated by a space, with no extra space at the end of the line.

样例输入

11 5
4 7
BOB5 DON2 FRA8 JAY9 KAT3 LOR6 ZOE1
1 4
ANN0 BOB5 JAY9 LOR6
2 7
ANN0 BOB5 FRA8 JAY9 JOE4 KAT3 LOR6
3 1
BOB5
5 9
AMY7 ANN0 BOB5 DON2 FRA8 JAY9 KAT3 LOR6 ZOE1
ZOE1 ANN0 BOB5 JOE4 JAY9 FRA8 DON2 AMY7 KAT3 LOR6 NON9

样例输出

ZOE1 2 4 5
ANN0 3 1 2 5
BOB5 5 1 2 3 4 5
JOE4 1 2
JAY9 4 1 2 4 5
FRA8 3 2 4 5
DON2 2 4 5
AMY7 1 5
KAT3 3 2 4 5
LOR6 4 1 2 4 5
NON9 0

先贴出两个超时的做法

做法二:
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

vector<string> vc[2501];//vc[i]存储i号课程有哪些学生


int main(){
    int N,K;
    int index,num;
    char name[5];
    string sname;
    
    while(scanf("%d%d",&N,&K)!=EOF){
        for(int i=1;i<=K;i++){
            scanf("%d%d",&index,&num);//第index号课程有num个学生选了
            while(num--){//num个学生分别是
                // cin>>name;
                scanf("%s",name);
                sname=name;
                vc[index].push_back(sname);
            }
        }
        while(N--){
            // cin>>name;
            // cout<<name;
            scanf("%s",name);
            sname=name;
            printf("%s", name);

            vector<int> couse;
            for(int i=1;i<=K;i++){
                if(find(vc[i].begin(),vc[i].end(),sname)!=vc[i].end()){
                    couse.push_back(i);
                }
            }
            printf(" %d", couse.size());
            for(int i=0;i<couse.size();i++){
                printf(" %d", couse[i]);
            }
            printf("\n");
        }
    }
    return 0;
}

做法一:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;

struct Student
{
    char name[5];
    vector<int> vc;
}Stu[40000];

int snum=0;//共有多少学生

int findindex(char name[]){
    for(int i=0;i<snum;i++){
        if(strcmp(name,Stu[i].name)==0){
            return i;
        }
    }
    strcpy(Stu[snum].name,name);
    return snum++;
}


int main(){
    int N,K;
    int index,num;
    char name[5];
    
    while(cin>>N>>K){
        snum=0;
        while(K--){//K种课
            cin>>index>>num;//第index号课程有num个学生选了
            while(num--){//num个学生分别是
                scanf("%s",name);
                Stu[findindex(name)].vc.push_back(index);
            }
        }
        while(N--){//输入N个学生,同时输出其选课情况
            scanf("%s",name);
            int n=findindex(name);
            printf("%s %d", name,Stu[n].vc.size());
            sort(Stu[n].vc.begin(),Stu[n].vc.end());
            for(int i=0;i<Stu[n].vc.size();i++){
                cout<<" "<<Stu[n].vc[i];
            }
            cout<<endl;
        }
    }
    
    return 0;
}

 

做法一在做法二超时后写的,越写越远。

现在来优化做法1,

做法1算法:利用结构体实现以字符串(学生名)为下标,vector存储改学生名对应的以选课号

但是findindex()函数实在是浪费了太多时间。能不能改成O(1)直接通过学生名找到对应的结构体而找到课号数组呢?

想到了4.2节的哈希散列(hash),不正是将字符串转换成唯一整数吗?转化为26进制数保证了hash的一一对应。

(字符串例子都一样,学过的东西要及时复习啊)

25*26*26*10+25*26*10+25*26+10=176160 数字也很小,空间换时间靠得住

当姓名能转换为数字后,就可以直接作为vector的下标了,方便极了,结构体都不需要了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;

int hashN(char a[]){
	/*int id=1;
	for(int i=0;i<3;i++){
		id=id*26+(a[i]-'A');
	}
	id=id*10+(a[3]-'0');
	return id;*/
	return (a[0]-'A')*26*26*10+(a[1]-'A')*26*10+(a[2]-'A')*10+a[3]-'0';

}

vector<int> vc[176160+10];

int main(){
	int N,K;
	int index,num;
	char name[5];
	
	while(scanf("%d%d",&N,&K)!=EOF){
		while(K--){//K种课
			scanf("%d%d",&index,&num);//第index号课程有num个学生选了
			while(num--){//num个学生分别是
				scanf("%s",name);
				vc[hashN(name)].push_back(index);
			}
		}
		while(N--){//输入N个学生,同时输出其选课情况
			scanf("%s",name);
			int n=hashN(name);
			printf("%s %d", name,vc[n].size());
			sort(vc[n].begin(),vc[n].end());
			for(int i=0;i<vc[n].size();i++){
				printf(" %d", vc[n][i]);
			}
			printf("\n");
		}
	}
	return 0;
}

 

问题 B: Student List for Course (25)

时间限制: 1 Sec  内存限制: 64 MB
提交: 223  解决: 135
[提交][状态][讨论版][命题人:外部导入]

题目描述

Zhejiang University has 40000 students and provides 2500 courses. Now given the registered course list of each student, you are supposed to output the student name lists of all the courses.

输入

Each input file contains one test case. For each case, the first line contains 2 numbers: N (<=40000), the total number of students, and K (<=2500), the total number of courses. Then N lines follow, each contains a student's name (3 capital English letters plus a one-digit number), a positive number C (<=20) which is the number of courses that this student has registered, and then followed by C course numbers. For the sake of simplicity, the courses are numbered from 1 to K.

输出

For each test case, print the student name lists of all the courses in increasing order of the course numbers. For each course, first print in one line the course number and the number of registered students, separated by a space. Then output the students' names in alphabetical order. Each name occupies a line.

样例输入

10 5
ZOE1 2 4 5
ANN0 3 5 2 1
BOB5 5 3 4 2 1 5
JOE4 1 2
JAY9 4 1 2 5 4
FRA8 3 4 2 5
DON2 2 4 5
AMY7 1 5
KAT3 3 5 4 2
LOR6 4 2 4 1 5

样例输出

1 4
ANN0
BOB5
JAY9
LOR6
2 7
ANN0
BOB5
FRA8
JAY9
JOE4
KAT3
LOR6
3 1
BOB5
4 7
BOB5
DON2
FRA8
JAY9
KAT3
LOR6
ZOE1
5 9
AMY7
ANN0
BOB5
DON2
FRA8
JAY9
KAT3
LOR6
ZOE1

先做这一题,估计前面一题就不会卡了,模仿着写‘’

#include<iostream>
#include<cstdio>
#include <vector>
#include <algorithm>
#include<cstring>
using namespace std;

vector<char*> vi[2510];

bool cmp(char* a,char* b){
	int n=strcmp(a,b);
	if(n<0) return true;
	return false;
}

int main(){
	int N,K;
	int num,index;
	
	while(scanf("%d%d",&N,&K)!=EOF){
		for(int i=0;i<N;i++){
			char* name=new char[5];//传递的是指针,<char*>始终都是这一块内存,不能共用,必须每次开辟新的
			scanf("%s%d",name,&num);
			for(int j=0;j<num;j++){//不能写i了  下标冲突
				scanf("%d",&index);
				vi[index].push_back(name);
			}
		}
		for(int i=1;i<=K;i++){
			printf("%d %d\n",i,vi[i].size());
			sort(vi[i].begin(),vi[i].end(),cmp);//c语言比较地址大小,而不是内容大小。必须自己写比较逻辑。还是用string方便
			for(int j=0;j<vi[i].size();j++){
				printf("%s\n", vi[i][j]);
			}
		}
	}
	
	return 0;
}

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页