《N诺机试指南》(九)查找、贪心、链表问题
1.查找问题:
二分查找:
例题:使用map解决查找问题
代码:
#include <bits/stdc++.h> using namespace std; //查找学生信息 struct Student{ string name; string sex; int age; string id; }stu[1005]; int main(){ int n; cin >> n; for(int i=0; i<n; i++){ cin >> stu[i].id >> stu[i].name >> stu[i].sex >> stu[i].age; } int m; cin >> m; string a[m]; for(int i=0; i<m; i++){ cin >> a[i]; } //查找信息 int flag = 0;//定义一个flag判断有没有找到 for(int i=0; i<m; i++){ for(int j=0; j<n; j++){ if(a[i]==stu[j].id){ cout << stu[j].id << " " << stu[j].name << " " << stu[j].sex << " " << stu[j].age << endl; flag = 1;//找到 break; } } if(!flag){//flag=0 cout << "No Answer" << endl; } } return 0; } //使用map查找学生信息 int main(){ int n, q; map<string, Student> M;//定义一个map映射 while( scanf("%d", &n)!=EOF ){ for(int i=0; i<n; i++){ Student s; cin >> s.id >> s.name >> s.sex >> s.age; M[s.id] = s;//将对应学生存到map对应id位置 } scanf("%d", &q); for(int i=0; i<q; i++){ string tempId; cin >> tempId; if( (M.find(tempId))!=M.end() ){ cout << M[tempId].id << " " << M[tempId].name << " " << M[tempId].sex << " " << M[tempId].age << endl; }else{ cout << "No Answer!" << endl; } } } return 0; }
2.贪心问题:
例题:
代码:
//小明买饮料喝问题 #include <bits/stdc++.h> using namespace std; struct node{ double w; double m;//w=价格,m=容量 }p[105]; bool cmp(node a, node b){ return a.w/a.m < b.w/b.m;//按照单价从小到大排序 } int main(){ int n, x; while(scanf("%d%d", &n, &x)!=EOF){ if(x==-1 && n==-1){//结束条件 break; } //输入数据 for(int i=1; i<=n; i++){ scanf("%lf%lf", &p[i].m, &p[i].w); } //按照单价排序 sort(p+1, p+1+n, cmp); double sum = 0; for(int i=1; i<=n; i++){ if(x >= p[i].w){ sum += p[i].m; x -= p[i].w }else{ sum += (x*p[i].m/p[i].w); break; } } printf("%.3lf\n", sum); } return 0; }
3.链表问题:
例题:约瑟夫环问题
代码:
//猴子报数=约瑟夫问题 #include <stdio.h> #include <malloc.h> using namespace std; struct node{ int num;//编号从1开始 struct node *next; }; int n, s, m;//n个猴子,从第s个开始报数,每走m个删掉一个猴子 //创建循环链表 struct node* create(){ struct node *head, *now, *pre; for(int i=1; i<=n; i++){ now = (struct node*)malloc(sizeof(node));//创建新节点 if(i==1){//如果是第一个,赋给head和pre head = now; pre = now; } //不是第一个节点 now->num = i; now->next = head;//循环链表,尾-->头 pre->next = now; pre = now;//最后把当前赋给pre,更新pre指针 } return head; } //打印结果 void print_node(struct node *head){ struct node *p; p = head; s = s - 1; //这里s要减去1,因为从头节点出发(head为1) //例如:s为2代表从第二个节点出发 //从head(为1)到s=2只需要走一步:1-->2 while(s--){ p = p->next; } int i = 1; printf("%d\n", p->num); while(p!=NULL){ if( p==p->next ){//如果是最后一个 printf("%d\n", p->num); break; } if( (i)%(m-1)==0 ){//找到第m-1步的节点 // i+1: 因为 printf("%d ", p->next->num);//输出第m个节点值 p->next = p->next->next;//删除第m个节点 } p = p->next;//更新p i++;//更新i } } int main(){ while(scanf("%d%d%d", &n, &s, &m)!=EOF){ if(n==0 && s==0 && m==0){ break; } struct node *head; head = create(); print_node(head); } return 0; }
重点是链表创建和打印输出: