使用说明书
百度网盘下载:http://pan.baidu.com/s/1dDci8cp
如果你是蓝桥杯选手,无法在蓝桥杯的练习系统刷题(如图1),或者不是VIP用户而不能做VIP题,可以在这个网站找到题目和测试数据下载:http://www.coolnote.cn/。由于无法在官方的OJ测试自己代码的正误,所以我开发了一款单机版的测评系统,由于兼容性问题(程序以C++为框架,调用命令行实现),可能win7及以上版本操作系统才可以使用。
图1 蓝桥杯练习系统界面
评测系统功能非常简洁,事实上我只写了200多行代码,所以只是作为应急之需,不可能代替正规的测评系统。测试时,只要你的源代码生成的可执行文件放在与“测试软件.exe”同目录即可,注意放入的可执行文件名称必须与所做题目相同,如我做了“带分数”这题,操作如图2所示。
图2 软件使用介绍
然后双击“测试软件.exe”即可,效果如图3所示。
图3 软件效果截图
如果有错误,你可以打开“2--当前题数据”文件夹,查看里面的文件,保存着最近一次测试的题目数据。其中"input"和"output"是从“1--测试数据”拷贝过来的官方版标准输入输出,"ans"是你的程序生成的答案。效果如图4所示。
图4 “2--当前题数据”文件夹
最后,读者在使用若干次,掌握了程序的原理后,可以自行添加新的题目数据进行测试。这里不在说明,留读者自己探索发现。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
“测试软件”源代码
#include <cstdio> #include <string> #include <string.h> #include <cstdlib> #include <iostream> #include <fstream> #include <vector> #include <cctype> #include <iomanip> #include <ctime> using namespace std; // 定义常量 const string File1 = "1--测试数据"; const string File2 = "2--当前题数据"; const string softName = "测试软件.exe"; string ProName; int testNum; int main() { // 函数声明 string get_ProName(); int get_testNum(); void Check(); // 初始化 time_t t = clock(); ProName = get_ProName(); testNum = get_testNum(); cout << "初始化用时:" << clock()-t << "ms\n\n"; // 判断 Check(); system("pause"); return 0; } string get_ProName() { void guide(); ifstream fin; // Step 1 system(("dir "+File1+" > tmp.txt").c_str()); // 用时50~77ms fin.open("tmp.txt"); vector<string> Pro; string s, name; while (fin >> s) { if (s.find(".txt") != string::npos) // 后缀为.txt { name = s.substr(0, s.find('-')); if (Pro.empty() || name!=*Pro.rbegin()) Pro.push_back(name); } } fin.close(); /* Debug:输出Pro列表 for (int i = 0; i < Pro.size(); i++) { cout << i+1 << " :" + Pro[i] << endl; } //*/ // Step 2 int ok, i; string pro; system("dir > tmp.txt"); fin.open("tmp.txt"); while (fin >> s) { if (s.find(".exe") != string::npos && s != softName) { // Step 3 pro = s.substr(0, s.find(".exe")); for (ok = i = 0; i < Pro.size(); i++) { if (Pro[i] == pro) { ok = 1; break; } } if (ok) break; } } fin.close(); system("del tmp.txt"); if (ok) return pro; else guide(); } int get_testNum() { void clear(string F); // Step 1 clear(File2); // Step 2 system(("copy "+File1+"\\"+ProName+"*.txt "+File2+" > tmp.txt").c_str()); // Step 3 ifstream fin("tmp.txt"); string s; int n; while (fin >> s) { if (s == "已复制") { fin >> n; break; } } fin.close(); return n/2; } void Check() { // 输出表头 cout << "完全正确:是指官方的output文件和您生成的ans文件完全匹配,没有任何差异\n"; cout << "基本正确:是指在忽略空格和回车符等空白字符影响下,两个文件内容相同\n"; cout << " 用 时:包含生成ans文件的时间,加上性能不稳定等原因,这里统计的值只能作为参考\n\n"; cout << "测试编号 " << "完全正确 " << "基本正确 " << "用时(单位ms)" << endl; time_t t, useTime; char num[5]; string s, s2; ifstream fin, fin2; char ch; for (int i = 1; i <=testNum; i++) { // Step 1 cout << setw(5) << i; // Step 2 // 下面先用s存储好命令文本,减小计时额外消耗 sprintf(num, "%d", i); // 把整数i变成字符串形式 s = ProName; // 调用exe // 找到输入文件 s = s + " <" + File2 + "\\" + ProName + "-input-" + num + ".txt"; // 找到输出文件 s = s + " >" + File2 + "\\" + ProName + "-ans-" + num + ".txt"; // 运行 t = clock(); system(s.c_str()); useTime = clock() - t; // Step 3 s = "fc " + File2 + "\\" + ProName + "-output-" + num + ".txt"; s = s + File2 + "\\" + ProName + "-ans-" + num + ".txt > tmp.txt"; fin.open("tmp.txt"); fin >> t; if (t) cout << setw(12) << "No"; else cout << setw(12) << "Yes"; fin.close(); // Step 4 bool same = 1; fin.open((File2 + "\\" + ProName + "-output-" + num + ".txt").c_str()); fin2.open((File2 + "\\" + ProName + "-ans-" + num + ".txt").c_str()); while (fin >> s && fin2 >> s2) if (s != s2) break; // 先去掉前面两份均相同的部分 //这里的尾部判断方法,一直觉得有点不太好 // 如果fin在此基础上,还能再读入s(s会变成不等于s2),则答案错误 do { if (s != s2) { same = 0; break; } } while (fin >> s); // 如果fin2还可以读入改变s2的字符,则答案错误 while (fin2 >> s2) { if (s != s2) { same = 0; break; } } if (same) cout << setw(12) << "Yes"; else cout << setw(12) << "No"; fin.close(); fin2.close(); cout << setw(12) << useTime << endl; } system("del tmp.txt"); } // 清空某个文件夹 void clear(string F) { system(("rmdir/s/q "+F).c_str());// 删除文件夹 system(("mkdir "+F).c_str()); // 再重新创建 } void guide() { cout << "(初次使用请忽略本句话)未在当前目录找到有效测试程序,请确认是否存在可执行文件或文件名正确性!\n\n"; int i, len; string star(80, '*'); for (i = 1; i < 80; i+=2) star[i] = ' '; cout << star << endl; string title("蓝桥杯测试软件 v0.5 By coder4101\n"); len = title.size(); cout << setw((80-len)/2+len) << title << endl; // 居中输出 cout << "使用指南\n\n"; cout << "1、只需把您编译出的exe可执行程序放在当前目录(与该\"测试软件.exe\"所在位置同级),"; cout << "并把名称改为对应的题目名。完成后,直接点击该\"测试软件.exe\"即可进行测试。\n\n"; cout << "2、若程序未AC,您可以在\""+File2+"\"目录下查看刚才的测试数据及结果,方便Debug。"; cout << "input和output标记的是标准的输入与输出,ans标记的是您的程序跑出的结果。\n\n"; cout << "3、本软件结果仅供参考,最终结论以官网为准。\n\n"; cout << "注:请勿修改以下三个名称:"+File1+","+File2+",测试软件.exe。"; cout << endl << star << endl; system("pause"); exit(0); }