竞赛讨论区 > A Singing Contest
头像
ccl66
编辑于 2018-08-05 09:57
+ 关注

A Singing Contest

  https://www.cnblogs.com/longl/p/9424539.html

思路:

由于每个选手的策略略都是尽可能赢,所以他该认输的时候只能认输。能赢的时候只要选权值大于对方最大值的最小值,大的留在后面不会更差,直接模拟即可。
我的模拟方法是:开一个二维的vector,第一维表示比赛场次,每次比赛完把结果保存到下一层,第二维表示每个歌手(注意不要开小了,我因为开小了TLE好几发,2^14 =16384 )。
在将结果记录到下一层的同时还要记录原有歌手的标号,以便最后输出结果。

代码:

#include
using namespace std;
const int maxn = 20000;
vector vec[20][maxn];///第一维表示比赛场次,第二维代表歌手
int id[maxn],v, tmp[maxn];
void init()
{
    for(int i=0;i<20;i++)
        for(int j=0;j<maxn;j++)
            vec[i][j].clear();
}
int main()
{
  //  printf("%d\n",1<<14);
    int t;
    scanf("%d",&t);
    for(int cas=1;cas<=t;cas++){
        int n;
        init();
        scanf("%d",&n);
        int cnt = 1<<n;
        for(int i=1;i<=cnt;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&v);
                vec[1][i].push_back(v);
            }
        }
        for(int i=1;i<=cnt;i++)id[i]=i;
        int singer = cnt;
        for(int i=1;i<n;i++){
            for(int j=1;j<=singer;j+=2){
                set st1,st2;
                set::iterator it;
                for(int k=0;k<vec[i][j].size();k++)st1.insert(vec[i][j][k]);
                for(int k=0;k<vec[i][j+1].size();k++)st2.insert(vec[i][j+1][k]);
                int v1=*(--st1.end());  ///歌手1的最大值
                int v2=*(--st2.end()); ///歌手2的最小值
                if(v1>v2){
                    st1.erase( st1.lower_bound(v2) );  ///在v1中找到比v2大的最小值
                    for(it=st1.begin();it!=st1.end();it++) ///复制到下一层
                        vec[i+1][(j+1)/2].push_back(*it);
                    tmp[(j+1)/2]=id[j];  ///保存原有id
                }else{
                    st2.erase( st2.lower_bound(v1) ); /// ///在v2中找到比v1大的最小值
                    for(it=st2.begin();it!=st2.end();it++)
                        vec[i+1][(j+1)/2].push_back(*it);
                    tmp[(j+1)/2]=id[j+1]; ///保存原有id
                }
            }
            singer>>=1;
            for(int j=1;j<=singer;j++)
                id[j]=tmp[j];
        }
        int ans=0;
        if(vec[n][1][0]>vec[n][2][0]) ans = id[1];
        else ans=id[2];
        printf("Case #%d: %d\n",cas,ans);
    }
    return 0;
}

全部评论

(0) 回帖
加载中...
话题 回帖

等你来战

查看全部

热门推荐