zoukankan      html  css  js  c++  java
  • 2018QBXT刷题游记(4)

    【2018QBXT刷题游记】

    Day1 TEST2

    T1 vote

    【问题描述】
    一场选举有三位选手分别编号为 1,2,3,还有两位评委 4,5。
    评委打分时会给出一个{1,2,3}的排列,表示评委对选手的喜爱程度。 例如评
    委给出一个排列{2,1,3},表示最喜欢 2,其次是 1,最后是 3。
    两位评委将分别给出排列 x、 y。你需要做的是综合考虑 x、 y,给出一个最
    终的排名 z。
    由于事先不知道 x、 y,所以你需要对于每一种不同的 x、 y,都提前设计好
    相应的 z。(显然 x、 y 有 36 种情况)
    正式地,你需要设计一个映射{X,Y}-->{Z},其中定义域是评委的排列,值
    域是你给出的最终排列。(定义域大小是 36,值域大小是 6,所以映射数量是
    6^36)。为了方便,用 z=f(x,y)表示评委打分是 x,y 时最终排名是 z。
    如果随便给一个映射,可能会被喷,比如两个评委都最喜欢 1,你最后却把
    1 排在最后。为了避免这种情况,你的映射可能需要满足几个条件:
    一致性:对于选手 a,b,如果两个评委都更喜欢 a,那么最终排名中 a 应当排
    在 b 前面。

    独立性: 定义函数(I(x,a,b)),如果排列 x 中 a 的位置比 b 靠前,那么 (I(x,a,b)=1). 否则 (I(x,a,b)=0)。 对于选手 a,b,考虑评委打分的两种情况((x1,y1)和(x2,y2)), 如果 (I(x1,a,b)=I(x2,a,b)),并 且 (I(y1,a,b)=I(y2,a,b)),那么 (f(x1,y1))(f(x2,y2)) 应当满足 (I(f(x1,y1),a,b)=I(f(x2,y2),a,b))

    非独裁: 如果对于任意的排列 x,y, (f(x,y)=x),那么称评委 4 独裁。如果对于任意的 x,y, (f(x,y)=y),那么称评委 5 独裁。非独裁就是两个评委都不独裁。

    【分析】这……一共就五种可能的m……第一次见到这种题,跪了。

    言归正传,这道题归根究底还是搜索,因为对于两个评委和映射值,都分别只有6种可能。我们用二进制数0,1,3,4,6,7表示可能出现的六种情况:

    比如:3=011,表示在这种情况下,1在2后面,1在3前面,2在3前面。

    于是dfs即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 8
    #define ll long long
    bool valid[MAXN]={1,1,0,1,1,0,1,1};
    int val[MAXN][MAXN];
    ll ans=0;int m;
    void judge(){
    	bool flag=1;
    	for(int i=0;i<MAXN;i++){
    		for(int j=0;j<MAXN;j++){
    			if(!valid[i]||!valid[j])continue;
    			if(val[i][j]!=i){flag=0;break;}
    		}if(flag==0)break;
    	}
    	if(flag)return;
    	flag=1;
    	for(int i=0;i<MAXN;i++){
    		for(int j=0;j<MAXN;j++){
    			if(!valid[i]||!valid[j])continue;
    			if(val[i][j]!=j){flag=0;break;}
    		}if(flag==0)break;
    	}
    	if(flag)return;
    	ans++;return;
    }
    
    void dfs(int x,int y){
    	if(x>=MAXN){
    		if(m==5){
    			judge();return;
    		}
    		else {ans++;return;}
    	}
    	int xx=x,yy=y+1;if(yy>=MAXN){yy=0;xx++;}
    	if(!valid[x]||!valid[y]){dfs(xx,yy);return;}
    	for(int i=0;i<MAXN;i++){
    		if(!valid[i])continue;
    		val[x][y]=i;
    		int tmp=(x^y^7);
    		if(m>3 && (x&tmp)!=(val[x][y]&tmp))//不满足一致性
    		continue;
    		bool flag=1;
    		for(int j=0;j<x;j++){
    			for(int k=0;k<MAXN;k++){
    				if(!valid[j]||!valid[k])continue;
    				if(j==x&&k==y)break;//xy前面的都结束了 
    				int a=(((x^j^7)&(y^k^7)));
    				int b=(val[j][k]^val[x][y]^7);
    				if(a!=(a&b)){flag=0;break;
    				}
    			}if(flag==0)break;
    		} 
    		if(flag)dfs(xx,yy);
    	}
    }
    void dfs2(int x,int y){
    	if(x>=MAXN){
    		ans++;return;
    	}
    	int xx=x,yy=y+1;if(yy>=MAXN){yy=0;xx++;}
    	if(!valid[x]||!valid[y]){dfs2(xx,yy);return;}
    	int tv=0;
    	for(int i=0;i<MAXN;i++){
    		if(!valid[i])continue;
    		val[x][y]=i;
    		int tmp=(x^y^7);
    		if((x&tmp)==(val[x][y]&tmp))tv++;
    	}
    	ans*=tv;
    	dfs2(xx,yy);
    }
    
    int main(){
    	scanf("%d",&m);
    	if(m==1){
    		printf("10314424798490535546171949056
    ");
    	}
    	else if(m==2){
    		ans=1;
    		dfs2(0,0);
    		printf("%lld
    ",ans);
    	}
    	else{
    		dfs(0,0);
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    LeetCode-079-单词搜索
    awk学习笔记
    Python实现排列组合算法
    python模拟登录人人
    Python的SQLite数据库使用方法
    C语言排序算法——插入排序算法
    C语言排序算法——简单选择排序算法
    C语言排序算法——冒泡排序算法
    Python学习——python的函数参数传递
    Python学习——实现secure copy功能
  • 原文地址:https://www.cnblogs.com/erutsiom/p/9904898.html
Copyright © 2011-2022 走看看