题意: 这题意很折腾人!(针对我这种code差还英文差的人!) 一共有32支队各自都有自己上季度的排名和自己属于的联盟;4个Seeding Pot
(储存罐),由顶向底各有八个队名;从Pot1按顺序倒空所有Pot(罐子倒空,是从顶到底倒顺序倒得);倒出的每个队分入到8组中去(A—H组)。
i) 同Pot队伍不能放入到相同的组去;(Pot里的队伍每个组放1个)
ii) 除了UEFA联盟可以每组最多有两支队伍外,其它联盟最多只能有每组一支;(UEFA联盟有14支队伍)
当前的拿出的队伍再确保满足上面规则且能分配好组的情况下,尽量分配到最左边的组,统计每个组里队伍的rank之和,按rank分数小的顺序且分数相同以组名的字典序顺序排序输出组名和rank和。
1、 队伍的上季度的排名和联盟号
总共有5个联盟:
UEFA 14支、CONMEBOL 5支、 CONCACAF 3支、AFC 5支、CAF 5支;
我们需要用数据结构来存储这些关系,并且方便查询,队名是主键,知道队名需要快速查询:其所属联盟UNION和Rank,很明显我们用Map来实现非常方便,因为Map的下标idx可以为任意类型,不像数组仅仅只能用0……n自然数。
map <string,int> MapTR;
map <string, string> MapTU;
map <string,int> YS;
string UNION[]={
"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 Rank[]={ 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
};
string TEAM[]={
"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"
};
//建立MapTR 、 MapTU对应关系
//建立YS对应联盟的排序标记
void init(){
for(int i=0;i<32;++i){
MapTR[TEAM[i]]=Rank[i];
MapTU[TEAM[i]]=UNION[i];
}
YS["UEFA"]=1;
YS["CONMEBOL"]=2;
YS["CAF"]=3;
YS["CONCACAF"]=4;
YS["AFC"]=5;
}
2、 输入部分: 4个Pot且由顶到底循序输入队名,且两个队名之间有”, “(一个“,”后有一个空格,坑人的是队名会有空格,字符串输入;遍历字符串,不为‘,’,即添加至字符串a后(‘+’运算);遇到‘,’,遍历跳过后面的字符‘ ’,记录a为一个队伍名,并清空a;
void Read(){
string a="\0";
int len=s.length();
for(int i=0;i<len;++i)
if(s[i]==','){
i++; team[num++]=a;
a="\0";
}else a+=s[i];
team[num++]=a;
}
3、DFS模拟这个过程,从第一个队开始,从A到H队,枚举它所分配的位置,必须满足题目要求的两个条件,并往下继续DFS,如果失败,即证明它不能为此位置,继续往右遍历合适的位置,如果均不可,即证实前面的队伍放置有问题,向上回溯false,表明错误,更新前面的队伍的放法;如果一直DFS到rt=32,即证实已经找到答案了!
bool dfs(int rt){
if(rt==32) return true;
int Union= YS[MapTU[team[rt]]];
for(int i=0;i<8;++i){
if(vis[rt/8][i]||!isTrue(i,Union)) continue;
vis[rt/8][i]=1; flag[i][Union]+=1; val[i]+=MapTR[team[rt]];
if(dfs(rt+1)) return true;
vis[rt/8][i]=0; flag[i][Union]-=1; val[i]-=MapTR[team[rt]];
}
return false;
}
代码:
/******************************************
2018 湖南多校赛(2) 分组对赛---(DFS)
******************************************/
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <algorithm>
#define llt long long
using namespace std;
map <string,int> MapTR;
map <string, string> MapTU;
map <string,int> YS;
string UNION[]={
"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 Rank[]={ 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
};
string TEAM[]={
"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"
};
//建立MapTR 、 MapTU对应关系
//建立YS对应联盟的排序标记
void init(){
for(int i=0;i<32;++i){
MapTR[TEAM[i]]=Rank[i];
MapTU[TEAM[i]]=UNION[i];
}
YS["UEFA"]=1;
YS["CONMEBOL"]=2;
YS["CAF"]=3;
YS["CONCACAF"]=4;
YS["AFC"]=5;
}
string s,team[33];
int flag[10][7],vis[5][10],idx[10],val[10];
int num=0;
bool isTrue(int rt,int Union){
return (flag[rt][Union]==0||(flag[rt][Union]==1&&Union==1));
}
bool dfs(int rt){
if(rt==32) return true;
int Union= YS[MapTU[team[rt]]];
for(int i=0;i<8;++i){
if(vis[rt/8][i]||!isTrue(i,Union)) continue;
vis[rt/8][i]=1; flag[i][Union]+=1; val[i]+=MapTR[team[rt]];
if(dfs(rt+1)) return true;
vis[rt/8][i]=0; flag[i][Union]-=1; val[i]-=MapTR[team[rt]];
}
return false;
}
void Read(){
string a="\0";
int len=s.length();
for(int i=0;i<len;++i)
if(s[i]==','){
i++; team[num++]=a;
a="\0";
}else a+=s[i];
team[num++]=a;
}
bool cmp(int a,int b){return val[a]<val[b]||(val[a]==val[b]&&a<b);}
int main(){
init();
while(1){
//freopen("out.txt","w",stdout);
num=0;
memset(val,0,sizeof(val));
memset(flag,0,sizeof(flag));
memset(vis,0,sizeof(vis));
int t=0;
for(int i=0;i<4;++i){
getline(cin,s);
if(s=="End") {t=1;break;}
Read();
}
if(t) break;
for(int i=0;i<8;++i) idx[i]=i;
dfs(0);
sort(idx,idx+8,cmp);
for(int i=0;i<8;++i)
cout<<(char)(idx[i]+'A')<<" "<<val[idx[i]]<<endl;
}
return 0;
}