论自动AC机
O(∩_∩)O哈哈~第一篇原创博客。终于结束了我“无敌转载王”的称号了!!!好开心!
(⊙v⊙)嗯,看到标题觉得我是神犇的人,请再次仔细看看标题,是“自动AC”,而非“AC自动”哦!这是利用lemon评测软件的bug实现AC目标的程序。
第一次接触到这个东西是今年暑假。我在XX学堂进行学习。一位DALAO AK了。我们都很震惊。这时一位仁兄举报了他,我们才发现他使用了自动AC机。
话不多说,先上代码。
#ifndef __linux__ #include<windows.h> #endif //#include<cstdlib> //#include<sys/types.h> //#include<unistd.h> #include<dirent.h> #include<string> #include<vector> #include<cstring> #include<algorithm> using namespace std; string f=__FILE__;int n,l; typedef std::pair<int,string> p; vector<p>v;char s[1000]; inline char*rread(int&r,char*s) { r=0; while(*s<'0'||*s>'9')s--; for(int b=1;*s>='0'&&*s<='9';b*=10,s--) r+=b*(*s-'0'); return s; } #include<iostream> int main() { f=f.substr(0,f.find_last_of('.',f.length())); #ifdef __linux__ DIR*dir=opendir(("../../data/"+f).c_str()); dirent*ptr; while((ptr=readdir(dir))!=NULL) if((l=strlen(ptr->d_name))>3&& (string(ptr->d_name).rfind(".out",l)==l-4|| string(ptr->d_name).rfind(".ans",l)==l-4)) { rread(n,ptr->d_name+strlen(ptr->d_name)); v.push_back(p(n,string(ptr->d_name))); } realpath(".",s); #else f=f.substr(f.find_last_of('\\',f.length())+1,f.length()); WIN32_FIND_DATA d; HANDLE hFind=FindFirstFile(("..\\..\\data\\"+f+"\\*").c_str(), &d); do if((l=strlen(d.cFileName))>3&& (string(d.cFileName).rfind(".out",l)==l-4|| string(d.cFileName).rfind(".ans",l)==l-4)){ rread(n,d.cFileName+strlen(d.cFileName)); v.push_back(p(n,string(d.cFileName))); }while (FindNextFile(hFind, &d) != 0); FindClose(hFind); GetModuleFileName(NULL,s,1000); #endif rread(n,rread(l,s+strlen(s))); sort(v.begin(),v.end()); #ifdef __linux__ system(("cp -f ../../data/"+f+'/'+v[n].second+" "+f+".out").c_str()); #else system(("copy ..\\..\\data\\"+f+'\\'+v[n].second+" "+f+".out").c_str()); #endif return 0; }
当时我们看到这个程序都惊呆了,因为根本看不懂……哪位看懂的DALAO也不用给我解释了,反正我不会懂的……
现在,我自己研究了一下,写了自己的简单易懂的版本……
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; char in[1000]; int main() { int num1,num2,id,n1,n2; freopen("****.in","r",stdin);//****为题目名称 freopen("****.out","w",stdout); scanf("%d",&n1); scanf("%d",&n2); fclose(stdin); for (int i=1;i<=10;i++) { sprintf(in,"..\\..\\data\\****\\****%d.in",i); freopen(in,"r",stdin); scanf("%d%d",&num1,&num2); if (num1==n1&&num2==n2) { id=i; break; } fclose(stdin); } sprintf(in,"..\\..\\data\\****\\****%d.ans",id); freopen(in,"r",stdin); string ans; cin>>ans; cout<<ans<<endl; return 0; }
非常简单,就是先读入两个数(当然可以多读几个,提高准确率,但一般两个足够了),然后进入到存数据的文件夹(即程序中的data文件夹)。利用循环,打开每一个输入文件,对比前两个数据,如果一样,那么说明我们找到了正确的读入文件(这就是为什么多读几个能更准确,但是一般来说前两个数都一样的不同两个输入文件太少了,所以一般两个即可)。记下这是第几组的输入文件,然后打开对应的输出数据,读入答案,输出。AC了!!!