信息学奥赛对拍写法

信息学奥赛对拍写法

  • 现在基本上都是在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\) 放在同一个目录下即可一用下面的两种方法进行对拍

  1. 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;
}
  1. \(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
posted @ 2020-10-05 20:12  ♞老姚♘  阅读(634)  评论(4编辑  收藏  举报