搜索

来源:互联网 发布:即时对战游戏源码 编辑:程序博客网 时间:2024/05/16 08:28

循环赛
总时间限制: 20000ms 单个测试点时间限制: 1000ms 内存限制: 65536kB

描述
n支队伍打比赛,每两支队伍恰好比赛一场。平局时各得1分,而有胜负时胜者3分,负者0分。
假设三支队伍得分分别为3, 3, 3,则可能有两种情况:
队伍A B C 得分
A - 3 0 3
B 0 - 3 3
C 3 0 - 3

队伍A B C 得分
A - 0 3 3
B 3 - 0 3
C 0 3 - 3

给出n支队伍的最终得分(即所有比赛均已结束),统计有多少种可能的分数表。

输入
第一行包含一个正整数n,队伍的个数。第二行包含n个非负整数,即每支队伍的得分。

输出
输出仅一行,即可能的分数表数目。保证至少存在一个可能的分数表。

样例输入
样例输入1:
3
3 3 3
样例输入2:
2
0 3
样例输入3:
3
4 1 2
样例输入4:
6
5 6 7 7 8 8

样例输出
样例输出1:
2
样例输出2:
1
样例输出3:
1
样例输出4:
121

数据规模
测试点 1 2~3 4~6 7~12 13~19 20~25
n 3 4 5 6 7 8

来源
CQOI

据说这就是hash剪枝,暂时不懂。
参考代码

#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <string>#include <iostream>#include <algorithm>#include <vector>#include <stack>#include <queue>#include <deque>#include <map>#include <set>using std::cin;using std::cout;using std::endl;const int maxn=10;int n;int score[maxn];int ans;inline int readIn(){    int a;    scanf("%d",&a);    return a;}long long hash(std::vector<int> &vec) //算出数组对应的hash值{    long long temp=0;    for(int i=0; i<vec.size(); i++)    {        temp=temp*29+vec[i];    }    return temp;}int searchGuest(int host, int guest, int scoreOfHost);std::map<long long, int> hashMap[maxn];int searchHost(int host = 1) //搜索主场{    if(host == n) //已经搜索完毕    {        return !score[host]; //如果分已经匹配完,说明有了一种方案    }    std::vector<int> hashOrigin;    for(int i=host; i<=n; i++)    {        hashOrigin.push_back(score[i]);    }    std::sort(hashOrigin.begin(),hashOrigin.end());    long long hashVal=hash(hashOrigin);    if(hashMap[host].count(hashVal)) return hashMap[host][hashVal];    else return hashMap[host][hashVal]=searchGuest(host, host+1, score[host]);}int searchGuest(int host, int guest, int scoreOfHost){    if(guest>n)    {        if(scoreOfHost) return 0;        else return searchHost(host+1);    }    if(scoreOfHost > (n-guest+1)*3) return 0;    int ans=0;    if(score[guest]>=3)    {        score[guest]-=3;        ans+=searchGuest(host, guest+1, scoreOfHost);        score[guest]+=3;    }    if(score[guest] && scoreOfHost)    {        score[guest]--;        ans+=searchGuest(host, guest+1, scoreOfHost-1);        score[guest]++;    }    if(scoreOfHost>=3)    {        ans+=searchGuest(host, guest+1,scoreOfHost-3);    }    return ans;}int main(){    n=readIn();    for(int i=1; i<=n; i++)    {        score[i]=readIn();    }    std::sort(score+1,score+1+n);    printf("%d",searchHost());    return 0;}
原创粉丝点击