信息学奥赛对拍写法
信息学奥赛对拍写法
-
现在基本上都是在linux下写代码,所以之给大家提供linux下的对拍版本。
-
以P1064 金明的预算方案为例,我们需要有一个根据题目要求的输入数据生成代码,我命名为 \(data.cpp\)。
-
下面的代码实际上没有严格按照题目要求做数据,但不影响对拍的结果。
-
\(data.cpp\)
#include <bits/stdc++.h> const int maxn=1e3; std::vector <int> a; int vis[maxn],zhu[maxn]; int main(){ srand(time(NULL));//随机种子 int m=1000,n=rand()%10+1; printf("%d %d\n",m,n); for(int i=1;i<=n;++i){ int v=rand()%100+1,p=rand()%5+1; int q=rand()%n+1; while(q==i)q=rand()%n+1;//自己不能是自己的主件 if(vis[i]){//如果i是主件 printf("%d %d 0\n",10*v,p);continue; } if(zhu[q])q=zhu[q];//如果q有自己的主件,则让i,q为兄弟 else{//如果q没有自己的主件,那q就成为主件 vis[q]=1; } zhu[i]=q; printf("%d %d %d\n",10*v,p,q); } return 0; }
-
自己根据题意写的代码
-
\(my.cpp\)
#include <bits/stdc++.h> const int maxn=60+5,maxv=32000+5; struct Edge{ int to,next; }e[maxn]; int dp[maxn][maxv],a[maxn],p[maxn]; int head[maxn],len,n,m; void Insert(int u,int v){ e[++len].to=v;e[len].next=head[u];head[u]=len; } void Init(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;++i){ int x;scanf("%d%d%d",&a[i],&p[i],&x);; Insert(x,i); } } void dfs(int u,int fa){ for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(v==fa)continue; dfs(v,u); for(int j=n-a[u];j>=a[v];--j) for(int k=0;k<=j;++k) dp[u][j]=std::max(dp[u][j],dp[u][j-k]+dp[v][k]); } if(u==0)return; for(int i=n;i>=0;--i){ if(i>=a[u]) dp[u][i]=dp[u][i-a[u]]+a[u]*p[u]; else dp[u][i]=0; } } void Solve(){ Init(); dfs(0,-1); printf("%d\n",dp[0][n]); } int main(){ Solve(); return 0; }
-
保证正确,但时间效率并一定高的代码,要求好写,准确,下面代码随便在网上找了份
-
\(force.cpp\)
#include <iostream> #define maxn 32005 using namespace std; int n,m; int v,p,q; int main_item_w[maxn]; int main_item_c[maxn]; int annex_item_w[maxn][3]; int annex_item_c[maxn][3]; int f[maxn]; int main(){ cin >> n >> m; for (int i=1;i<=m;i++){ cin >> v >> p >> q; if (!q){ main_item_w[i] = v; main_item_c[i] = v * p; } else{ annex_item_w[q][0]++; annex_item_w[q][annex_item_w[q][0]] = v; annex_item_c[q][annex_item_w[q][0]] = v * p; } } for (int i=1;i<=m;i++) for (int j=n;main_item_w[i]!=0 && j>=main_item_w[i];j--){ f[j] = max(f[j],f[j-main_item_w[i]]+main_item_c[i]); if (j >= main_item_w[i] + annex_item_w[i][1]) f[j] = max(f[j],f[ j - main_item_w[i] - annex_item_w[i][1] ] + main_item_c[i] + annex_item_c[i][1]); if (j >= main_item_w[i] + annex_item_w[i][2]) f[j] = max(f[j],f[ j - main_item_w[i] - annex_item_w[i][2] ] + main_item_c[i] + annex_item_c[i][2]); if (j >= main_item_w[i] + annex_item_w[i][1] + annex_item_w[i][2]) f[j] = max(f[j],f[ j - main_item_w[i] - annex_item_w[i][1] - annex_item_w[i][2] ] + main_item_c[i] + annex_item_c[i][1] + annex_item_c[i][2]); } cout << f[n] << endl; return 0; }
有了上面的三份代码,并把三个程序编译生成的三个可执行程序\(data,my,force\) 放在同一个目录下即可一用下面的两种方法进行对拍
- c++版本
#include <bits/stdc++.h>
int main(){
int i=0;
while(1){
++i;
system("./data > data.in");//把data.cpp输出数据写到data.in
system("./my < data.in > my.out");//my.cpp从data.in读取数据,结果输出到my.out
system("./force < data.in > force.out");//force.cpp从data.in读入数据,结果写到force.out
if(system("diff my.out force.out"))//比较两个输出是否相同
break;//不相同就跳出
else
printf("%d AC\n",i);
}
return 0;
}
- \(shell\) 版本
#! /bin/bash
while true;do
./data > data.in #生成的数据写入到文件data.in
./my < data.in > my.out # my从data.in读人数据,结果输出到my.out
./force < data.in > force.out #force从data.in读入数据,结果写入到force.out
if diff my.out force.out;then # 比较两个文件内容是否完全一样
printf "ac\n"
else
printf "wa\n"
exit 0
fi
done
hzoi