• 信息学奥赛对拍写法


    信息学奥赛对拍写法

    • 现在基本上都是在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
      ",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
      ",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
      ",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
      ",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
    ",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
    "
    	else
    		printf "wa
    "
    		exit 0
    	fi
    done
    
  • 相关阅读:
    golang 数据结构 优先队列(堆)
    leetcode刷题笔记5210题 球会落何处
    leetcode刷题笔记5638题 吃苹果的最大数目
    leetcode刷题笔记5637题 判断字符串的两半是否相似
    剑指 Offer 28. 对称的二叉树
    剑指 Offer 27. 二叉树的镜像
    剑指 Offer 26. 树的子结构
    剑指 Offer 25. 合并两个排序的链表
    剑指 Offer 24. 反转链表
    剑指 Offer 22. 链表中倒数第k个节点
  • 原文地址:https://www.cnblogs.com/hbhszxyb/p/13771344.html
Copyright © 2020-2023  润新知