zoukankan      html  css  js  c++  java
  • UVA

    /*
      这题其实不难,而且很贴近生活啊!等ACM题刷累了的时候,不妨把这个代码再多加些功能,写成一个小小的项目试试,我觉得会挺有意义
      
      体现了的知识点:
      为了避免浮点数的误差,一般在按小数点输入之前,要先将它和一个较小的数EPS(通常用1e-5)相加
      
      打脸了...WA了将近一天,各种调试和找错,整整找了一天,没错,就是整整一天,不是上学的一天,是暑假的一整天,什么都不做专门调这道题的那种一天,好几次都崩溃到想放掉这道题...想着,WA就WA吧,反正真正比赛的时候,应该不会出这种题目
      (这脸打得也太响了,我本来还想着,这道题看思路似乎挺简单,要不就不做了,先自学些数据结构等别的ACM题,结果...太轻视这题了啊!~)
      
      但是想了想,不能这样啊,凡事只有0次和无数次的区别...如果我这次因为一直WA就放弃了,下次就可以因为这个数据结构/算法没学过,这道题太难,这道题一直没思路又没题解根本做不出...等等各种其他的理由放弃掉别的题。要放弃可以有很多理由~可是既然给自己划定了某个目标,就不要畏难,死磕也要磕到底,哪怕是付出再多时间,也一定要磕下来...战线可以拉长,不求在最近就弄明白,可是绝对不能在心里告诉自己:我不管了,太难了,这道题我就是做不出来了...
      
      嗯,对自己还是不能放太多水,平时放的水,最后都会在WA时,变成自己深沉的泪水,hhh~
      
    */


    /*
      版本1
      这个题目其实挺好理解,我就不解释我的代码了,来讲讲我究竟是怎么WA的吧!
      
      UVA的输出数据里面,应该有格式或者中西文标点的错误,因为我直接把UVA里面的这句输出复制下来
      
      "Showing the ranklist hurts students’ self-esteem. Don’t do that."
      
      提交代码的时候,就是WA
      
      而我自己敲了这句以后,就只是改了这句,改为
      "Showing the ranklist hurts students' self-esteem. Don't do that."
      
      就AC了...惊不惊喜,意不意外,我会说,没想到还有这个天坑吗! T^T...做这道题一定要注意注意再小心,至少这句话,不要直接从UVA的样例输出里面复制
      (我会说复制,本来就是为了避免出现,中西文标点等看不出差别的问题,UVA的数据居然还这样坑我,真是天坑啊!卒~)
      
      吐槽完毕,上代码...可以说是很艰难的AC了...唉
      (对了,最终真正找到这个bug,还要多亏了命令行的神操作..下次专门写一篇博文讲下,我究竟是怎么发现,错误居然在这里的...最关键的突破点,是因为利用了命令行的txt比较功能)
      
      话说,当时没想到还真的有这个操作,抱着试试的心态随手一搜,居然真的有...搜索引擎可真是个好东西啊!hhhhhhh....(大家多多百度谷歌吧,真的很多时候会有意外的收获呢!)
      
      从此以后,我觉得我就可以借助重定向和这个比较功能,很方便地加各种输出语句来调试了...ohyeah!!~
      
      不知道什么时候能来填(如何利用命令行发现隐藏很深的WA原因)这个坑,就先把这个命令行神操作的网址放着好了
      https://jingyan.baidu.com/article/19020a0a1dd04a529c284272.html
    */

    #include <iostream>
    #include <iomanip>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    //#define debug
    using namespace std;
    const int maxn = 1e5; 
    const double EPS = 1e-5;
    int n = 0;
    int CID, _score[4], sum;
    string SID, name, s;
    const string course[] = {"Chinese", "Mathematics", "English", "Programming"};
    const string words[] = {"Number of students who failed all subjects: ", "Number of students who passed 1 or more subjects: ", "Number of students who passed 2 or more subjects: ", "Number of students who passed 3 or more subjects: ", "Number of students who passed all subjects: "}; 
    
    struct student
    {
    	int CID, score[5]; // Chinese, Math, English, Programming, total
    	bool del;
    	double average;
    	string name, SID;
    }stu[maxn];
    
    
    void Print_Menu()
    {
    	cout << "Welcome to Student Performance Management System (SPMS)." << endl << endl << "1 - Add" << endl << "2 - Remove" << endl << "3 - Query" << endl << "4 - Show ranking" << endl << "5 - Show Statistics" << endl << "0 - Exit" << endl << endl; 
    }
    
    int valid() // 检查是否合法,如果输入的SID已经输入过了,则该输入不合法,因而不处理该输入 
    {
    	for (int i = 0; i < n; i++)
    	if (!stu[i].del)
    	if (stu[i].SID == SID)
    	return 0;
    	return 1;
    }
    
    int Rank (int k)
    {
    	int cnt = 0;
    	for (int i = 0; i < n; i++)
    	{
    		if ( !stu[i].del && stu[i].score[4] > stu[k].score[4] ) cnt++;
    	}
    	return cnt + 1;
    }
    
    void Add()
    {
    	while (1)
    	{
    		sum = 0;
    		cout << "Please enter the SID, CID, name and four scores. Enter 0 to finish." << endl;
    		cin >> SID;
    		if (SID == "0") return;
    		cin >> CID >> name;
    		for (int i = 0; i < 4; i++)
    		{
    			cin >> _score[i];
    			sum += _score[i];
    		}
    		if (!valid()) cout << "Duplicated SID." << endl;
    		else
    		{
    			stu[n].SID = SID; stu[n].CID = CID; stu[n].name = name;
    			for (int i = 0; i < 4; i++) stu[n].score[i] = _score[i];
    			stu[n].score[4] = sum;
    			stu[n].average = sum * 1.0 / 4 + EPS;
    			stu[n].del = false;
    			n++;
    		}
    	}
    }
    
    void Remove()
    {
    	while (1)
    	{
    		cout << "Please enter SID or name. Enter 0 to finish." << endl;
    		cin >> s;
    		if (s == "0") break;
    		int cnt = 0;
    		for (int i = 0; i < n; i++)
    		{
    			if ( !stu[i].del && (stu[i].SID == s || stu[i].name == s) )
    			{
    				stu[i].del = true;
    				++cnt;
    			}
    		}
    		cout << cnt << " student(s) removed." << endl;
    	}
    }
    
    void Query()
    {
    	while (1)
    	{
    		cout << "Please enter SID or name. Enter 0 to finish." << endl;
    		cin >> s;
    		if (s == "0") return;
    		for (int i = 0; i < n; i++)
    		{
    			char c = ' ';
    			if ( !stu[i].del && (stu[i].SID == s || stu[i].name == s) )
    			{
    				cout << Rank(i) << c << stu[i].SID << c << stu[i].CID << c << stu[i].name << c;
    				for (int j = 0; j < 5; j++) cout << stu[i].score[j] << c;
    				cout << fixed << setprecision(2) << stu[i].average << endl;
    			}
    		}
    	}
    }
    
    void Statistics()
    {
    	cout << "Please enter class ID, 0 for the whole statistics." << endl;
    	int cid, i, j, passed, failed, total, cnt, cnt1;
    	cin >> cid;
    	int p[5]; // p[i]记录通过了i门课程的学生 
    	char c;// c == ' '
    	memset(p, 0, sizeof(p)); // 每次调用都要清空p,p[i]代表了当前指定的范围的学生中,有p[i]或以上的同学通过了该课程 
    	if (!cid) //cid == 0, 0 for the whole statistics,枚举所有学生,不论其班级是什么
    	{
    		for (int i = 0; i < 4; i++) // 枚举科目 
    		{
    			passed = 0, failed = 0, total = 0, cnt = 0;
    			for (j = 0; j < n; j++)
    			{
    				if (!stu[j].del) // 枚举没被删除的同学
    				{
    					cnt++;
    					total += stu[j].score[i];
    					if (stu[j].score[i] >= 60) passed++;
    					else failed++;
    				} 
    			}
    			cout << course[i] << endl << "Average Score: " << fixed << setprecision(2) << (cnt ? total * 1.0 / cnt + EPS : 0) << endl
    				 << "Number of passed students: " << passed << endl << "Number of failed students: " << failed << endl << endl;
    		}
    		
    		for (int i = 0; i < n; i++) // 枚举没被删除的学生 
    		{
    			if (!stu[i].del) 
    			{
    				cnt1 = 0;
    				for (int j = 0; j < 4; j++) // 枚举他上的每门课程,计算多少门及格
    				{
    					if (stu[i].score[j] >= 60) cnt1++;
    				}  
    				//更新统计通过i门课(i [0, 4]) 的学生数
    				if (!cnt1) p[0]++;
    				else
    				for (int k = 1; k <= cnt1; k++) p[k]++; 
    			}
    		}
    		cout << "Overall:" << endl;
    		for (int i = 4; i >= 0; i--) cout << words[i] << p[i] << endl;
    		cout << endl;
    	}
    	else // 仅找班级号与cid相同的,且没被删除的学生 
    	{
    		for (int i = 0; i < 4; i++)
    		{
    			passed = failed = total = cnt = 0;
    			for (int j = 0; j < n; j++) 
    			{
    			 	if (!stu[j].del && stu[j].CID == cid)
    			 	{
    			 		cnt++;
    			 		total += stu[j].score[i];
    			 		if (stu[j].score[i] >= 60) passed++;
    			 		else failed++;
    				}
    			}
    			cout << course[i] << endl << "Average Score: " << fixed << setprecision(2) << (cnt ? total * 1.0 / cnt + EPS : 0) << endl
    				 << "Number of passed students: " << passed << endl << "Number of failed students: " << failed << endl << endl;
    			
    		}
    		
    		for (int i = 0; i < n; i++) // 枚举没被删除的,且在指定班级的所有学生 
    		{
    			if (!stu[i].del && stu[i].CID == cid) 
    			{
    				cnt1 = 0;
    				for (int j = 0; j < 4; j++) // 枚举他上的每门课程,计算多少门及格
    				{
    					if (stu[i].score[j] >= 60) cnt1++;
    				}  
    				//更新统计通过i门课(i [0, 4]) 的学生数
    				if (!cnt1) p[0]++;
    				else
    				for (int k = 1; k <= cnt1; k++) p[k]++; 
    			}
    		}
    		cout << "Overall:" << endl;
    		for (int i = 4; i >= 0; i--) cout << words[i] << p[i] << endl;
    		cout << endl;
    	}
    }
    
    int main()
    {
    	cin.tie(0);
    	cin.sync_with_stdio(false);
    	#ifdef debug
    	freopen("E:\in.txt", "r", stdin);
    	freopen("E:\out.txt", "w", stdout);
    	#endif
    	
    //	n = 0; 
    	int choice;
    	bool flag = true;
    	while(flag)
    	{
    		Print_Menu();
    		cin >> choice;
    		switch(choice)
    		{
    			case 0: flag = false; break;
    			case 1: Add(); break;
    			case 2: Remove(); break;
    			case 3: Query(); break;
    			case 4: cout << "Showing the ranklist hurts students' self-esteem. Don't do that." << endl; break;
    			case 5: Statistics(); break;
    		}
    	}
    	
    	#ifdef debug
    	fclose(stdin);
    	fclose(stdout);
    	#endif
    	return 0;
    } 


    /*
      版本2
      版本2与版本1的不同点是:
      1. 合并了删除操作和查询操作的大部分代码。因为删除删除操作和查询的输入是一样的,并且,操作上也有大部分的重叠
      2. 输出班级信息的部分,改为了两个函数,并且,将指定班级的输出和所有班级的输出合并了,因此只需要在特定的有选择语句的地方,除了判断输入数字是否与学生的班级号相等,再额外加上判断输入数字是否为0(因为为0时表示输出所有班级的信息,因而不再需要考虑学生的班级是否符合要求,直接全加上即可)...因而,合并了所有班级和指定班级的情况,大大精简了代码
      
      又及,这个改进思路是从这个blog上看到的,然后我再以我最初敲好的代码,借鉴这个思路,作了一些简化和修改
      http://blog.csdn.net/kun768/article/details/43816501
      
      (据说还是汝佳老师的源代码),而且真是很简洁啊!一开始看到这道题的时候,我还以为不到将近200行一定搞不定,没想到...果然汝佳老师的思路就十分清晰,很清楚什么操作可以合并部分代码,什么情况可以合并大部分代码,因此代码也就简洁优美了很多
       
    */ 

    #include <iostream>
    #include <iomanip>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    //#define debug
    using namespace std;
    const int maxn = 1e5;
    const double EPS = 1e-5;
    int n = 0;
    int CID, _score[4], sum;
    string SID, name, s;
    const string course[] = {"Chinese", "Mathematics", "English", "Programming"};
    const string words[] = {"Number of students who failed all subjects: ", "Number of students who passed 1 or more subjects: ", "Number of students who passed 2 or more subjects: ", "Number of students who passed 3 or more subjects: ", "Number of students who passed all subjects: "}; 
    struct student
    {
    	int CID, score[5]; // Chinese, Math, English, Programming, total
    	bool del;
    	double average;
    	string name, SID;
    }stu[maxn];
    
    
    void Print_Menu()
    {
    	cout << "Welcome to Student Performance Management System (SPMS)." << endl << endl << "1 - Add" << endl << "2 - Remove" << endl << "3 - Query" << endl << "4 - Show ranking" << endl << "5 - Show Statistics" << endl << "0 - Exit" << endl << endl; 
    }
    
    int valid() // 检查是否合法,如果输入的SID已经输入过了,则该输入不合法,因而不处理该输入 
    {
    	for (int i = 0; i < n; i++)
    	{
    		if (!stu[i].del && stu[i].SID == s) return 0;
    	}
    	return 1;
    }
    
    int Rank (int k)
    {
    	int cnt = 0;
    	for (int i = 0; i < n; i++)
    	{
    		if ( !stu[i].del && stu[i].score[4] > stu[k].score[4] ) cnt++;
    	}
    	return cnt + 1;
    }
    
    void Add()
    {
    	while (1)
    	{
    		cout << "Please enter the SID, CID, name and four scores. Enter 0 to finish." << endl;
    		sum = 0;
    		student in;
    		cin >> s;
    		in.SID = s;
    		if (s == "0") break;
    		cin >> in.CID >> in.name;
    		for (int i = 0; i < 4; i++)
    		{
    			cin >> in.score[i];
    			sum += in.score[i];
    		}
    		if (!valid()) cout << "Duplicated SID." << endl;
    		else
    		{
    			in.score[4] = sum;
    			in.average = sum / 4.0 + EPS; 
    			in.del = false;
    			stu[n++] = in;
    		}
    	}
    }
    
    void DQ(const int op) // op代表操作,如果为 0,表明输出的是要删除的,如果为 1,表明输入的只是需要查询 
    {
    	while (1)
    	{
    		cout << "Please enter SID or name. Enter 0 to finish." << endl;
    		cin >> s;
    		if (s == "0") break;
    		int cnt = 0;
    		for (int i = 0; i < n; i++)
    		{
    			if ( !stu[i].del && (stu[i].SID == s || stu[i].name == s) )
    			{
    				if (!op) //删除 
    				{
    					stu[i].del = true;
    					++cnt;
    				}
    				else
    				{
    					char c = ' ';
    					cout << Rank(i) << c << stu[i].SID << c << stu[i].CID << c << stu[i].name << c;
    					for (int j = 0; j < 5; j++) cout << stu[i].score[j] << c;
    					cout << fixed << setprecision(2) << stu[i].average << endl;
    				}
    				
    			}
    		}
    		if (!op) cout << cnt << " student(s) removed." << endl;
    	}
    }
    
    void output (const int no, const int type)
    {
    	int sum = 0, cnt1 = 0, cnt2 = 0;
    	for (int i = 0; i < n; i++)
    	if ( !stu[i].del && (no == 0 || no == stu[i].CID) )
    	{
    		sum += stu[i].score[type];
    		if (stu[i].score[type] >= 60) cnt1++;
    		else cnt2++; 
    	}
    	//#改到这里啦! 
    	cout << "Average Score: " << fixed << setprecision(2) <<( (cnt1 + cnt2 != 0)?(sum * 1.0 / (cnt1 + cnt2) + EPS ): 0 )<< endl
    		 << "Number of passed students: " << cnt1 << endl << "Number of failed students: " << cnt2 << endl << endl;
    	
    }
    
    void Print()
    {
    	int p[5];
    	memset(p, 0, sizeof(p));
    	cout << "Please enter class ID, 0 for the whole statistics." << endl;
    	int num; cin >> num;
    	for (int i = 0; i < 4; i++)
    	{
    		cout << course[i] << endl;
    		output(num, i);
    	}
    	cout << "Overall:" << endl;
    	for (int i = 0; i < n; i++)
    	{
    		if ( !stu[i].del && ( num == 0 || stu[i].CID == num ) )
    		{
    			int tp = 0;
    			for (int j = 0; j < 4; j++)
    			if (stu[i].score[j] >= 60)
    			tp++;
    			
    			if (!tp) p[0]++;
    			else
    			{
    				for (int k = 1; k <= tp; k++)
    				p[k]++;
    			}
    		}
    	}
    	for (int i = 4; i >= 0; i--)
    	cout << words[i] << p[i] << endl;
    	cout << endl;
    }
    
    int main()
    {
    	cin.tie(0);
    	cin.sync_with_stdio(false);
    	#ifdef debug
    	freopen("E:\in.txt", "r", stdin);
    	freopen("E:\out.txt", "w", stdout);
    	#endif
    	
    	int choice;
    	bool flag = true;
    	n = 0;
    	while(flag)
    	{
    		Print_Menu();
    		cin >> choice;
    		switch(choice)
    		{
    			case 0: flag = false; break;
    			case 1: Add(); break;
    			case 2: DQ(0); break;
    			case 3: DQ(1); break;
    			case 4: cout << "Showing the ranklist hurts students' self-esteem. Don't do that." << endl; break;
    			case 5: Print(); break;
    		}
    	}
    	
    	#ifdef debug
    	fclose(stdin);
    	fclose(stdout);
    	#endif
    	return 0;
    } 


  • 相关阅读:
    Spring中的BeanUtils与apache commons中的BeanUtils用法[1]
    C# rmi例子
    跨时钟域设计的一点总结
    FPGA跨时钟域异步时钟设计的几种同步策略-可编程逻辑-与非网
    关于FPGA异步时钟采样--结绳法的点点滴滴
    sigaction函数解析
    可重入函数
    SCHED_OTHER,SCHED_FIFO,SCHED_RR-intentness-ChinaUnix博客
    qt安装教程
    VS2013 平台下搭建 QT5.3 开发环境
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789530.html
Copyright © 2011-2022 走看看