湖南多校对抗赛 CSUOJ 2030: World Cup Draw dfs 阅读理解题 水题

Description
The draw for the 2018 FIFA World Cup took place on Friday, December 1 at the State Kremlin Palace in Moscow. The FIFA released the draw procedure a few months ago on the official FIFA website, explained below. The 32 qualified finalists are first distributed into four seeding pots based on the FIFA ranking for October 2017. Pot 1 contains the host Russia and the seven highest ranking teams; the next eight highest ranked teams in Pot 2, and so on. Then, teams are drawn into eight groups of four, which are labeled from A to H. The pots are emptied into groups in order from Pot 1 through Pot 4. The draw must satisfy the following two rules: (i) no teams from the same pot can be drawn into the same group. (ii) with the exception of UEFA, which has more qualified teams (14) than the groups (8), no teams from the same confederation can be drawn in the same group. Moreover, at most two teams from UEFA can be drawn in the same group. Order groups alphabetically from A to H with A and H respectively being the leftmost and rightmost groups. At each step of the draw, the drawn team x from Pot i is placed in the first group from left (starting from group A) not violating rules (i) and (ii) and being possible to distribute the remaining teams (not drawn teams so far) of Pot i in the next steps without violating rules (i) and (ii). Computer scientists have assured FIFA that it is always possible to distribute teams of Pot i into groups satisfying rules (i) and (ii), regardless of how the other teams in Pot 1 through Pot i − 1 are distributed into groups. The table below shows the pots. In this table, x (r, c) means that team x belongs to confederation c, and its rank in the FIFA ranking is r. You are to write a program to simulate the draw and report the groups for the given draw order for each pot.

这里写图片描述
Input
There are multiple test cases in the input. Each test case consists of 4 lines. The ith line presents all 8 team names (as written in the table) in Pot i in the draw order (from left to right). Team names are separated by ”,” and there may exist a space before or after team names. In all test cases, Russia is the first drawn country in Pot 1 due to the old tradition of placing the host country in group A. The input terminates with “End” that should not be processed.

Output
For each test case, simulate the draw based on the given draw order, and compute the weight of each group which is the summation of team ranks in that group. For each group, print the group name (an uppercase letter) and its weight separated by a space in one line. This must be done in the increasing order of the weights from the strongest group (the group with the minimum weight) to the weakest group (the group with the maximum weight). In the case of a tie, print based on the alphabetical order of group names.

Sample Input
Russia, Germany, Brazil, Portugal, Argentina, Belgium, Poland, France
Spain, Peru, Switzerland, England, Colombia, Mexico, Uruguay, Croatia
Denmark, Iceland, Costa Rica, Sweden, Tunisia, Egypt, Senegal, Iran
Serbia, Nigeria, Australia, Japan, Morocco, Panama, South Korea, Saudi Arabia
Russia, Germany, Brazil, Portugal, Argentina, Belgium, Poland, France
Spain, Peru, Switzerland, England, Colombia, Mexico, Uruguay, Croatia
Denmark, Iceland, Costa Rica, Sweden, Tunisia, Egypt, Senegal, Iran
Serbia, Nigeria, Morocco, Panama, Australia, Japan, South Korea, Saudi Arabia
End
Sample Output
B 73
C 78
E 83
D 92
H 107
F 110
G 118
A 136
C 77
B 78
E 83
D 87
H 108
F 110
G 118
A 136

题意:
真阅读理解题。。。
题面给出了32只球队所属的联盟 排名 分为4个pot。
现在要按照如下要求分成8组。 编号为A-H
1. 分组顺序按照pot从小到大,pot从左到右依次处理。
2. 对于当前要处理球队 其分组要满足以下要求

(i) no teams from the same pot can be drawn into the same group.
同一个pot的队伍不能被分在同一组
(ii) with the exception of UEFA, which has more qualified teams (14) than the groups (8), no teams from the same confederation can be drawn in the same group. Moreover, at most two teams from UEFA can be drawn in the same group.
每一组最多容纳两只UEFA联盟的球队,其它联盟的球队最多容纳一只。

现在要你模拟这个过程,输出每组的球队的排名之和。输出顺序以排名之和为第一关键字 以 队伍编号为第二关键字 从小到大输出。

真的是个智障题。。。。 模拟这个过程 就是一个dfs枚举。随谈最多有32!种情况 但实际上会搜到的远没有这么多。 加点剪枝直接按照题目描述模拟就好了。跑了8ms
坑点在于, South Korea, Saudi Arabia South Korea, Saudi Arabia South Korea, Saudi Arabia
md 这两个国家名之间有空格。。。。 我是按照空格来分解国家名的 然后一直wa。。。 智障的一匹。不然可以出5题的

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include<cstring>
#include <map>
#include <vector>
using namespace std;
vector<string> V;
bool check(char ch) {
    return (ch>='a' && ch<='z')|| (ch>='A' && ch<='Z');
}
class Node {
public:
    int id,soced,sizes;
    map<string,int > MS;
    bool vis[5];
    Node(int id=0,int soced=0):id(id),soced(soced) {
        MS.clear();
        memset(vis,0,sizeof vis);
        sizes=0;
    }
    void clear() {
        id=0;
        soced=0;
        sizes=0;
        MS.clear();
        memset(vis,0,sizeof vis);
    }
    bool operator < (const Node &b) {
        if(soced== b.soced) {
            return id<b.id;
        }
        return soced<b.soced;
    }
};
string tname[40]= {"Russia","Germany","Brazil","Portugal","Argentina","Belgium","Poland","France","Spain","Peru","Switzerland","England","Colombia","Mexico","Uruguay","Croatia","Denmark","Iceland","Costa Rica","Sweden","Tunisia","Egypt","Senegal","Iran","Serbia","Nigeria","Australia","Japan","Morocco","Panama","South Korea","Saudi Arabia"};
string team[50]= {"UEFA","UEFA","CONMEBOL","UEFA","CONMEBOL","UEFA","UEFA","UEFA","UEFA","CONMEBOL","UEFA","UEFA","CONMEBOL","CONCACAF","CONMEBOL","UEFA","UEFA","UEFA","CONCACAF","UEFA","CAF","CAF","CAF","AFC","UEFA","CAF","AFC","AFC","CAF","CONCACAF","AFC","AFC"};
int ranks[50]= {65,1,2,3,4,5,6,7,8,10,11,12,13,16,17,18,19,21,22,25,28,30,32,34,38,41,43,44,48,49,62,63};
map<string, int >M;
void solve(string str) {
    int len=str.length();
    int i=0;
    while(i<len) {
        while(i<len && !check(str[i])) {
            i++;
        }
        string cnt;
        while(i<len && (check(str[i])||str[i]==' ')) {
            cnt+=str[i];
            i++;
        }
        V.push_back(cnt);
    }
}
Node node[10];
bool dfs(int now) {
    //cout<<now<<":"<<V[now]<<endl;
    if(now>=32)
        return 1;
    int id=M[V[now]];
    for(int i=0; i<8; i++) {
        if(node[i].vis[now/8]) continue;
        if(node[i].sizes>=4) continue;
        if(team[id]=="UEFA") {
            if(node[i].MS[team[id]]>=2) continue;
        } else if(node[i].MS[team[id]]>=1) continue;
        node[i].vis[now/8]=1;
        node[i].sizes++;
        node[i].MS[team[id]]++;
        node[i].soced+=ranks[id];
        bool flag=dfs(now+1);
        if(flag) {
            return flag;
        } else {
            node[i].vis[now/8]=0;
            node[i].sizes--;
            node[i].MS[team[id]]--;
            node[i].soced-=ranks[id];
        }
    }
    return 0;
}
void init() {
    for(int i=0; i<8; i++) {
        node[i].clear();
    }
    V.clear();
    for(int i=0; i<8; i++) {
        node[i].id=i;
    }
}
int main() {
    string str;
    for(int i=0; i<32; i++) {
        M[tname[i]]=i;
    }
    int flag=1;
    while(1) {
        init();
        for(int i=0; i<4; i++) {
            getline(cin,str);
            solve(str);
            if(V[0]=="End"){
                flag=0;
                break;
            }
        }
        if(flag==0) break;
        dfs(0);
        sort(node,node+8);
        for(int i=0; i<8; i++) {
            cout<<(char)(node[i].id+'A')<<" "<<node[i].soced<<endl;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值