[SOJ1006] Team Rankings

94 篇文章 4 订阅
74 篇文章 1 订阅

用枚举法实现
代码如下:
//我是先用全排列生成了全部的串,再写的
全排列生成代码,点击可看
枚举的时候用了减枝,所以可能会稍微快点
但是emmm
看完师兄们的解法只需要0.00sec之后,我这个0.02sec的菜鸡就不知道该说什么好了

代码如下:(会比较好理解)

#include <iostream>
#include <vector>
using namespace std;
#include <cstring>
#include <algorithm>
string strSet[] = {
"ABCDE",
"ABCED",
"ABDCE",
"ABDEC",
"ABECD",
"ABEDC",
"ACBDE",
"ACBED",
"ACDBE",
"ACDEB",
"ACEBD",
"ACEDB",
"ADBCE",
"ADBEC",
"ADCBE",
"ADCEB",
"ADEBC",
"ADECB",
"AEBCD",
"AEBDC",
"AECBD",
"AECDB",
"AEDBC",
"AEDCB",
"BACDE",
"BACED",
"BADCE",
"BADEC",
"BAECD",
"BAEDC",
"BCADE",
"BCAED",
"BCDAE",
"BCDEA",
"BCEAD",
"BCEDA",
"BDACE",
"BDAEC",
"BDCAE",
"BDCEA",
"BDEAC",
"BDECA",
"BEACD",
"BEADC",
"BECAD",
"BECDA",
"BEDAC",
"BEDCA",
"CABDE",
"CABED",
"CADBE",
"CADEB",
"CAEBD",
"CAEDB",
"CBADE",
"CBAED",
"CBDAE",
"CBDEA",
"CBEAD",
"CBEDA",
"CDABE",
"CDAEB",
"CDBAE",
"CDBEA",
"CDEAB",
"CDEBA",
"CEABD",
"CEADB",
"CEBAD",
"CEBDA",
"CEDAB",
"CEDBA",
"DABCE",
"DABEC",
"DACBE",
"DACEB",
"DAEBC",
"DAECB",
"DBACE",
"DBAEC",
"DBCAE",
"DBCEA",
"DBEAC",
"DBECA",
"DCABE",
"DCAEB",
"DCBAE",
"DCBEA",
"DCEAB",
"DCEBA",
"DEABC",
"DEACB",
"DEBAC",
"DEBCA",
"DECAB",
"DECBA",
"EABCD",
"EABDC",
"EACBD",
"EACDB",
"EADBC",
"EADCB",
"EBACD",
"EBADC",
"EBCAD",
"EBCDA",
"EBDAC",
"EBDCA",
"ECABD",
"ECADB",
"ECBAD",
"ECBDA",
"ECDAB",
"ECDBA",
"EDABC",
"EDACB",
"EDBAC",
"EDBCA",
"EDCAB",
"EDCBA"
};

struct Node{
    char x,y;
    Node(char a='A',char b='A'):x(a),y(b){};
}; 

int label[120];//总共有120种可能排法,只需要找到最简单的那个就好了
int minAns = 1<<30;
string ans; 
string DataSet[101];
int n; 

int jiao(vector<Node> v1,vector<Node> v2){
    int a = 0;
    for (int i = 0; i < v1.size(); ++i) {
        for (int j = 0; j < v2.size(); ++j){
            if (v1[i].x == v2[j].x && v1[i].y == v2[j].y){
                a++;
                break;
            }
        }
    }
    return a;
}
int cHelp(int p,int q){
    //返回第p个序列和第q个序列之间的差距
    // p在strSet中找,q在DataSet中找 
    vector<Node> v1,v2;//v1放的是strSet[p]的二元子串;v2放的是v2放的是DataSet[q]的二元子串 
    for (int i = 0; i < 4;++i){
        for (int j = i + 1; j < 5; ++j){
            v1.push_back(Node(strSet[p][i], strSet[p][j]));
            v2.push_back(Node(DataSet[q][i], DataSet[q][j]));
        }
    }
    // sort and  
    int num = jiao(v1,v2);
    return 10 - num;
} 
// calculate
void calculate(int temp){ // temp在strSet中  
    //计算第temp个字符的sum和
    //实现一个减枝,如果目前加的和已经大于了当前最小的那个,就可以不用来看了
    for (int j = 0; j < n; ++j){
        label[temp] +=  cHelp(temp, j);
        if (label[temp] > minAns) {
            break;
        } // 减枝部分 
    }
    if (label[temp] < minAns){
        ans = strSet[temp];
        minAns = label[temp]; // 这是数值更新部分 
    }
}
int main(){
    while (cin >> n && n){
        for (int i = 0; i < n; ++i){
            cin >> DataSet[i];
        }
        memset(label,0,sizeof(label));//标记复原为0; 
        minAns = 1<<30;
        ans = "";
        //初始化 
        for (int i = 0; i < 120; ++i){
            calculate(i);
        } 
        cout << ans<<" is the median ranking with value "<<minAns<<"."<< endl;
    }
} 

最后,老套路,宣传一波自己的公众号!(求关注哇!)
本人中大一肥宅,欢迎大家关注,请扫下面的二维码(〃’▽’〃)


二维码

如果觉得有帮助的话,可以扫码,赞赏鼓励一下!谢谢!


这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥宅_Sean

公众号“肥宅Sean”欢迎关注

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值