【编程训练-考研上机模拟】综合模拟1-2019浙大上机模拟(晴神)

3月9日综合模拟

A - 古剑奇谭三:封印解除

Problem Description

众所周知,在游戏《古剑奇谭三》中一种被封印的宝箱,而解除封印的过程则是一个小游戏,在这个小游戏中有一个圆盘,如下图所示。为了简单起见,本题只考虑这个小游戏初见时的最简单规则,后续随着游戏主线的推进,这个小游戏会产生好几种变体,转来转去的,会加大本题难度,所以都不考虑了。

可以看到这个圆盘的上下左右各有一块扇状碎片,这四块碎片是可以进出圆盘内外的,而游戏的目标则是让玩家操作上下左右按键,来让这四块扇形最终都处于圆盘内部。

具体规则是,当玩家按上下左右键中的一个时,会使当前方向与相邻两个方向,共三块碎片切换内外状态,即如果按“上”键,会让上左右三个方向的碎片改变内外状态;按“右”键,会让右上下三个方向的碎片改变内外状态;按“下”键,会让下左右三个方向的碎片改变内外状态;按“左”键,会让左上下三个方向的碎片改变内外状态。

例如,在下图的情形下,上和左两个方向的碎片在圆盘内,右和下两个方向的碎片在圆盘外。

在按了“上”键之后,会改变上左右三块碎片的内外状态,所以变为了下图,即右方向的碎片在圆盘内,上左下三个方向的碎片在圆盘外。

接着按“左”键,让上左下三块碎片切换内外状态,就会使得四个碎片全都在圆盘内部,封印解除成功。

现在给出四块碎片的初始内外状态,求接下来的每次按键后四块碎片的内外状态。

注意:

  1. 游戏有操作次数限制K,如果操作了K次之后四块碎片仍然未全都在圆盘内部,那么视作封印解除失败,输出NO。
  2. 如果在到达K次操作限制之前,能够让四块碎片全部处于圆盘内部,那么视作封印解除成功,输出YES,剩余的按键不需要再处理。

Input

每个输入文件一组数据。

第一行为四个用空格隔开的字符串,分别为上、右、下、左四个方向的碎片的初始内外状态,其中IN表示在圆盘内部,OUT表示在圆盘外部。

第二行为一个正整数K(K<=10),表示操作次数限制。

接下来K行,每行为一个字符串,表示玩家当前按了哪个键,其中UPRIGHTDOWNLEFT分别表示上、右、下、左。

Output

对每次操作都输出一行,即按了对应按键之后上、右、下、左四个方向的碎片的内外状态,每两个字符串之间用一个空格隔开,行末不允许有多余的空格。

最后一行输出YESNO,分别表示封印解除成功与失败。

Sample Input 1

IN OUT OUT IN
5
UP
LEFT
DOWN
UP
RIGHT

Sample Output 1

OUT IN OUT OUT
IN IN IN IN
YES

Sample Input 2

IN OUT OUT IN
1
UP

Sample Output 2

OUT IN OUT OUT
NO

分析:简单模拟,注意判定初始状态是否已经满足要求

#include<bits/stdc++.h>
using namespace std;
void turn(string &str){
    if(str == "IN")str = "OUT";
    else str = "IN";
}
int main(){
    unordered_map<string, int>mp;
    mp["UP"] = 0, mp["RIGHT"] = 1, mp["DOWN"] = 2, mp["LEFT"] = 3;
    vector<string>state(4);
    for(int i = 0; i < 4; ++i)cin>>state[i];
    int K, cnt = 0;
    bool flag1 = false;
    cin>>K;
    if(state[0] == "IN" && state[1] == "IN" && state[2] == "IN" && state[3] == "IN"){
        printf("YES\n");
        return 0;
    }
    while(cnt < K){
        string t;
        cin>>t;
        int d1 = (mp[t] + 3) % 4, d2 = mp[t], d3 = (mp[t] + 1) % 4;
        turn(state[d1]);
        turn(state[d2]);
        turn(state[d3]);
        cnt++;
        bool flag2 = true;
        for(int i = 0; i < 4; ++i){
            printf("%s", state[i].c_str());
            if(i < 3)printf(" ");
            else printf("\n");
            if(state[i] == "OUT")flag2 = false;
        }
        if(flag2 == true){
            flag1 = true;
            break;
        }
    }
    printf("%s", flag1 == true ? "YES" : "NO");
    return 0;
}

B - 古剑奇谭三:关键系统

Problem Description

众所周知,游戏《古剑奇谭三》中很多系统。

一些玩家喜欢这次大气的剧情系统,一些玩家喜欢这次做得还挺不错的3D全即时制战斗系统:

一些玩家喜欢有着中国特色的2D皮影龙宫场景与横版战斗系统:

一些玩家把游戏玩成了“钓鱼奇谭”:

一些玩家把游戏玩成了“打牌奇谭”:

也有一些玩家则玩成了“家园奇谭”,其中家园中有让很多人沉迷的种菜系统、养殖系统、养鱼系统、采矿系统、寻宝系统、研究系统、能玩成“我的世界奇谭”的造房子系统等等。

我的世界之天鹿城露天电影院

许多玩家沉迷于战斗、钓鱼、打牌、种菜、造房子,主线五分钟、XX两小时,除了这作本身做得比较好玩的原因之外,还有一个原因是一个系统的产物可能可以被用在另一个系统中,例如寻宝系统得到的材料可以用来造房子;种菜可以种出药,就可以在打怪的时候使用“神农剑法”(emmm……就是吃药的别名,“只要我的药足够,BOSS就打不死我”、“神农剑法,鬼神皆斩”之类的……);等等。于是系统之间就有了联系,一同构成了游戏的可玩性。

现在我们定义,对两个系统,只要有其中一个系统的产物能用在另一个系统中,那么就称这两个系统“有关联”,且它们处于同一个“关联网”中;如果一个系统与一个关联网中的某个系统有关联,则称这个系统也在这个关联网中。在此基础上,在一个关联网中,如果让其中一个系统消失,会导致这个关联网被分裂成两个或多个关联网,那么把这个系统称为“关键系统”。

例如有四个系统ABCD,其中A和B有关联、B和C有关联、B和D有关联,那么ABCD在同一个关联网中,且系统B是关键系统。

现在告诉你系统之间的关联关系,请判断一些系统是否是关键系统。

Input

每个输入文件一组数据。

第一行两个整数N、M(0<N<=1000, 0<M<=N*(N-1)/2),分别表示系统数量与关联数量,系统下标为从1到N。

接下来M行,每行两个正整数u、v(1<=u,v<=N, u!=v),表示系统u和系统v有关联。

然后一个正整数K(K<=10),表示查询个数。

接下来一行为K个正整数,表示需要判断的系统编号。

Output

输出K行,按顺序给出每个查询系统的判断结果,如果是关键系统则输出YES,否则输出NO。

Sample Input 1

4 4
1 2
1 3
1 4
2 3
4
1 2 3 4

Sample Output 1

YES
NO
NO
NO

Sample Input 2

9 7
1 2
2 3
4 5
5 6
5 7
7 8
7 9
9
3 2 1 9 8 7 6 5 4

Sample Output 2

NO
YES
NO
NO
NO
YES
NO
YES
NO

分析:注意理解理解关键系统的概念,即为删除该节点后图的联通分量会变多,因此需要计算初始的联通块的个数

#include<bits/stdc++.h>
using namespace std;
const int nmax = 1010;
int fath[nmax];
bool isRoot[nmax];
void init(){
    for(int i = 0; i < nmax; ++i){
        fath[i] = i;
        isRoot[i] = false;
    }
}
int findF(int x){
    int z = x;
    while(x != fath[x])x = fath[x];
    while(z != fath[z]){
        int temp = fath[z];
        fath[z] = x;
        z = temp;
    }
    return x;
}
void Union(int a, int b){
    int fa = findF(a), fb = findF(b);
    if(fa != fb)fath[fa] = fb;
}
int main(){
    unordered_map<int, bool>mp;
    int n, m, K;
    scanf("%d %d", &n, &m);
    init();
    for(int i = 0; i < m; ++i){
        int v, u;
        scanf("%d%d", &u, &v);
        mp[u * nmax + v] = mp[v * nmax + u] = true;
        Union(u, v);
    }
    int cnt0 = 0;
    for(int j = 1; j <= n; ++j)isRoot[findF(j)] = true;
    for(int j = 1; j <= n; ++j)if(isRoot[j] == true)cnt0++;
    scanf("%d", &K);
    for(int i = 0; i < K; ++i){
        int v;
        scanf("%d", &v);
        init();
        for(int j = 1; j <= n; ++j){
            if(j == v)continue;
            for(int k = j + 1; k <= n; ++k){
                if(k == v)continue;
                if(mp.count(j * nmax + k) != 0)Union(j, k);
            }
        }
        int cnt = 0;
        for(int j = 1; j <= n; ++j)isRoot[findF(j)] = true;
        for(int j = 1; j <= n; ++j)if(isRoot[j] == true)cnt++;
        printf("%s\n", cnt <= cnt0 + 1 ? "NO" : "YES");
    }
    return 0;
}

C - 古剑奇谭三:迷宫救援

Problem Description

众所周知,在游戏《古剑奇谭三》中有许多迷宫。其中一个迷宫有一个特点,那就是其中一条原本可以通行的道路在游戏中被阻断,玩家只能绕路前往剧情点。由于剧情点处有人质需要拯救,男主角北洛想要尽快穿过迷宫,所以一定是选择能到达剧情点的最短路前进。假设北洛知道迷宫长啥样,他也事先知道有一条道路被阻断了,但他并不知道是迷宫中的哪条道路被阻断了(被阻断的道路在一开始就已经被阻断)。请帮他提前计算一下,在最糟糕的情况下,最快需要多久才能到达剧情点。

被挡住去路的道路:

Input

每个输入文件中一组数据。

第一行为两个正整数N、M(0<N<=500、0<M<=N*(N-1)/2),分别表示路口的个数、道路的条数。接下来M行,每行三个整数u、v、w,分别表示一条道路的起点编号、终点编号、通过它需要的时间(1<=u,v<=N, 1<=w<=10000, u!=v),每条边都可以双向通行。假设所有路口的编号为从1到N,且1号为北洛的初始所在地,N号为剧情点。数据保证没有重边。

Output

输出一个正整数,表示在最糟糕的情况下,最快到达剧情点需要的时间。如果在最糟糕的情况下无法到达剧情点,那么输出It‘s a bug!!!

Sample Input 1

4 5
1 2 1
1 3 2
1 4 1
2 4 2
3 4 1

Sample Output 1

3

Sample Input 2

4 3
1 2 1
2 3 1
3 4 1

Sample Output 2

It's a bug!!!

分析:如果删除的边是最短路径上的边,最后的结果会受到影响,否则可以通过最短路径到达目的地,因此先用一次dijsktra求出最短路径(任选一条即可),然后逐次尝试,如果tmax == inf表明此时不可到达终点,输出"It‘s a bug!!!"

(第一次写的代码是选出了所有的最短路径,用起点和终点不在一个联通块判定不可达)

#include<bits/stdc++.h>
using namespace std;
const int nmax = 510, inf = (1 << 31) - 1;
int mp[nmax][nmax];
int fath[nmax];
bool isRoot[nmax];
void init(){
    for(int i = 0; i < nmax; ++i){
        fath[i] = i;
        isRoot[i] = false;
    }
}
int findF(int x){
    int z = x;
    while(x != fath[x])x = fath[x];
    while(z != fath[z]){
        int temp = fath[z];
        fath[z] = x;
        z = temp;
    }
    return x;
}
void Union(int a, int b){
    int fa = findF(a), fb = findF(b);
    if(fa != fb)fath[fa] = fb;
}
int d[nmax];
bool vis[nmax];
vector<int>pre[nmax];
void dij(int s, int v1, int v2, int n){
    fill(d, d + nmax, inf);
    fill(vis, vis + nmax, false);
    d[s] = 0;
    for(int i = 1; i <= n; ++i){
        int u = -1, MIN = inf;
        for(int j = 1; j <= n; ++j){
            if(vis[j] == false && d[j] < MIN){
                MIN = d[j];
                u = j;
            }
        }
        if(u == -1)return;
        vis[u] = true;
        for(int j = 1; j <= n; ++j){
            if((u == v1 && j == v2) || (u == v2 && j == v1))continue;
            if(mp[u][j] != inf){
                if(d[u] + mp[u][j] < d[j]){
                    d[j] = d[u] + mp[u][j];
                    if(v1 == -1 && v2 == -1){
                        pre[j].clear();
                        pre[j].push_back(u);
                    }
                }else if(d[u] + mp[u][j] == d[j] && v1 == -1 && v2 == -1){
                    pre[j].push_back(u);
                }
            }
        }
    }
}
unordered_map<int, int>edge;
vector<int>ans;
void dfs(int s, int e){
    ans.push_back(s);
    if(s == e){
        for(int i = 1; i < ans.size(); ++i){
            int u = ans[i], v = ans[i - 1];
            if(u > v)swap(u, v);
            edge[u] = v;
        }
        return;
    }
    for(int i = 0; i < pre[s].size(); ++i){
        dfs(pre[s][i], e);
    }
    ans.pop_back();
}
int main(){
    int n, m;
    scanf("%d%d", &n, &m);
    fill(mp[0], mp[0] + nmax * nmax, inf);
    for(int i = 0; i < m; ++i){
        int u, v, t;
        scanf("%d%d%d", &u, &v, &t);
        mp[u][v] = mp[v][u] = t;
    }
    //求最短路径和最短路径上的边
    dij(1, -1, -1, n);
    dfs(n, 1);
    //求tmax
    int tmax = -1;
    bool flag = true;
    for(auto it = edge.begin(); it != edge.end(); ++it){
        int u = it->first, v = it->second;
        init();
        for(int j = 1; j <= n; ++j){
            for(int k = j + 1; k <= n; ++k){
                if((j == u && k == v) || (j == v && k == u))continue;
                if(mp[j][k] != inf)Union(j, k);
            }
        }
        if(findF(1) != findF(n)){
            flag = false;
            break;
        }
        dij(1, u, v, n);
        tmax = max(tmax, d[n]);
    }
    if(flag == false)printf("It's a bug!!!\n");
    else printf("%d\n", tmax);
    return 0;
}

D - 古剑奇谭三:千秋戏王

Problem Description

众所周知,游戏《古剑奇谭三》又被称作“打牌奇谭”,此牌名为「千秋戏」。

简单来说,千秋戏是一个凑对子算积分的小游戏,规则如下:

总牌堆中共54张牌(记为numCardTotal),每张牌的花色是春夏秋冬之一,游戏中每次需要新牌时都会按顺序从总牌堆最上方取。

游戏开局时,从总牌堆中依次按 我方手牌->对方手牌->公共牌池->我方手牌->对方手牌->公共牌池->... 的顺序发牌,使得双方玩家手上各有十张牌(记为numCardForPlayer)、公共牌池有八张牌(记为numCardForPublic)。

游戏中的说明图如下。为了简化问题,本题不考虑有特殊效果的珍稀牌。

游戏以我方先手,两方回合交替进行。

我方的回合,我方可以选择手牌中的一张牌、和公共牌池中的一张同花色的牌一起收入我方牌组,我方的总得分增加这两张牌的基础分之和(每张牌的基础分都相同,记基础分为score)。

以下图为例,可以选择手牌中花色为冬的“百里屠苏”、与公共牌池中花色同样为冬的“沈夜”一同加入我方牌组,我方得分增加它们的基础分共4分。

而如果当前收入我方牌组的牌能和我方牌组中已有的牌形成组合、或者这两张收入牌组的牌本身也能形成组合,那么我方的总得分将额外增加对应的组合分。对方回合同理。

以下图为例,在我方牌组中已经有“沈夜”、本回合加入“流月城”的情况下,我方得分除了基础分以外,还能增加由“沈夜”和“流月城”组成的组合“永夜寒沉”的组合分4分。

当然,构成组合的牌可能不止两张,例如组合“红月”的素材就是5张牌,可以获得组合分40分。

每次双方从公共牌池中选择一张牌收入牌组后,系统会自动将总牌堆最上方的那张牌加入公共牌池。

如果某回合手牌中没有和公共牌池中同花色的牌,那么只选择手牌中的一张牌收入牌组(实际游戏中此条规则更为复杂,为了简单起见将此条规则进行了简化)。

双方都把手牌全部出完时,游戏结束,此时总得分更高的玩家将获得胜利。

假设对方玩家是人工智障AI,每回合总是优先选择自己手牌中牌名的字典序最小的牌,如果这张牌在公共牌池中有相同花色的牌,那么将这张牌和公共牌池中相同花色的牌中字典序最小的那张一起收入牌组;如果这张牌在公共牌池中没有相同花色的牌,那么再考虑手牌中字典序第二小的牌,依此类推。如果手牌中的所有牌都没能在公共牌池中找到相同花色的牌,那么只把手牌中字典序最小的牌收入牌组。

求我方在游戏结束时能获得的最高总得分,以及我方获得最高总得分时对方的总得分。

来吧,赌上千秋戏王的称号,与人工智障AI决一胜负,不死不休!!!

Input

每个输入文件一组数据。

第一行为三个正整数numCardForPlayer、numCardForPublic、score(0<numCardForPlayer<=5、0<numCardForPublic<=5、0<score<=5),分别代表、开局时给双方玩家各发的牌数、开局时给公共牌堆发的牌数、每张牌的基础分。总牌堆中的牌数numCardTotal等于numCardForPlayer*4+numCardForPublic,不需要专门输入。

接下来的numCardTotal行为总牌堆从上往下顺序的所有牌的信息,每行为用一个空格隔开的一个字符串与一个字母,分别表示牌名与花色。其中牌名为仅由大小写字母组成的字符串,长度最大为20个字符;花色的取值为字母C(春)、X(夏)、Q(秋)、D(冬)中的一个。数据保证牌名唯一,且每个牌名只会出现一张(也就不可能出现两张牌的牌名相同、花色不同的情况了)。

接下来一个整数numCombine(0<=numCombine<=10),表示可以形成的组合的种类数。

接下来numCombine行为可以形成的组合,每行以两个正整数K、S开头(0<S<=100),分别表示形成该组合需要的牌数、能获得的组合分值,然后是K个字符串,表示形成该组合需要的K个牌名。数据保证同一个组合中的牌名唯一,且所有牌名都在总牌堆中出现过。

Output

用一个空格隔开的两个整数,分别表示我方在游戏结束时能获得的最高总得分、我方获得最高总得分时对方的总得分。行末不允许有多余的空格。如果我方有多种能获得最高总得分的方法,那么从中选择对方能获得的最低得分。

Sample Input

2 3 2
BaiLiTuSu D
HongYu Q
TianYongCheng D
TaoHuaGu C
QingYuTan Q
YouDu D
AnLu Q
FangLanSheng C
FengQingXue C
GuJianFenJi X
YinQianShang Q
6
2 3 BaiLiTuSu TianYongCheng
2 4 HongYu AnLu
2 4 BaiLiTuSu FengQingXue
2 4 FengQingXue YouDu
2 5 BaiLiTuSu GuJianFenJi
3 10 BaiLiTuSu FengQingXue TaoHuaGu

Sample Output

26 10

惨兮兮,题都没读懂,代码当然是看题解啦~

分析:

1.思路:直接枚举,由于对方的出牌规则确定,但是己方的出牌方案需要是全局最优,因此需要遍历所有方案

2. 数据结构:

(1) 总牌堆vector<string>cards

(2)我方手牌、对手手牌、公共牌池 vectoe<string>myHandCard, rivalHandCard, publicCard

(3)我方牌组、对方牌组 vector<string> myDeck, rivalDeck

(4)组合 Combine combine[maxNumCombine],将组合记录定义为结构体,组合的分数和对应的牌组作为成员变量

(5)花色,牌名保证是唯一的,使用一个映射即可unordered_map<string, char>color

3.实现过程:

(1)我方回合dfs(int numRound)

处理我方回合时,枚举我方手牌,从手牌中取出,加入我方牌组;再在公共牌池找同花色,如果找到,将其加入我放牌组并从牌池删除,从总牌堆中取出一张放入牌池;如果找不到同花色的,将手牌放入牌组即可;然后进行对方回合;对方回合结束后,需要将我方牌组、手牌、公共牌池、牌堆恢复状态

(2)对手回合rivalRound(int numRound)

处理对方回合时,按照字典序找花色匹配的牌,找不到时选手牌中的第一张,出牌过程和我方相同。对方结束后,开始下一轮dfs(numRound - 1)

(3)计算得分calScore<vector<string> deck)

总分为基础得分+组合分,计算组合分时,用includes()逐个判断组合是否在牌组中

4. 借鉴点

(1)变量的命名。名字最好反应内涵,ide有代码补全的,不难写

(2)dfs的应用。以前都是dfs自己套自己,这次居然和别的相互套。。。

#include<bits/stdc++.h>
using namespace std;
const int MAXPlayerCard = 10;
const int MAXPublicCard = 10;
const int MAXCombine = 15;
string card[MAXPlayerCard * 4 + MAXPublicCard];//总牌堆
unordered_map<string, char>color;//花色
struct Combine{
    vector<string>cards;
    int score;
}combine[MAXCombine];
//数量
int numCardForPlayer, numCardForPublic, numCardTotal, score, numCombine, idxPublic;
vector<string>myHandCard, rivalHandCard, publicCard;
vector<string>myDeck, rivalDeck;
int calScore(vector<string>deck){
    sort(deck.begin(),deck.end());
    int resScore = score * (int)deck.size();
    for(int i = 0; i < numCombine; ++i){
        if(includes(deck.begin(), deck.end(), combine[i].cards.begin(), combine[i].cards.end())){
            resScore += combine[i].score;
        }
    }
    return resScore;
}
void dfs(int numRound);
//对方回合
void rivalRound(int numRound){
    int idxRivalHandCard = -1, idxPublicCard = -1;
    for(int i = 0; i < rivalHandCard.size(); ++i){
        for(int j = 0; j < publicCard.size(); ++j){
            if(color[rivalHandCard[i]] == color[publicCard[j]]){
                idxRivalHandCard = i;
                if(idxPublicCard == -1 || publicCard[j] < publicCard[idxPublicCard]){
                    idxPublicCard = j;
                }
            }
        }
        if(idxRivalHandCard != -1)break;
    }
    if(idxRivalHandCard == -1)idxRivalHandCard = 0;
    string tempRivalCard = rivalHandCard[idxRivalHandCard];
    rivalDeck.push_back(tempRivalCard);
    rivalHandCard.erase(rivalHandCard.begin() + idxRivalHandCard);
    if(idxPublicCard != -1){
        string tempPublicCard = publicCard[idxPublicCard];
        rivalDeck.push_back(tempPublicCard);
        publicCard.erase(publicCard.begin() + idxPublicCard);
        publicCard.push_back(card[idxPublic++]);
        dfs(numRound - 1);
        idxPublic--;
        publicCard.pop_back();
        rivalDeck.pop_back();
        publicCard.insert(publicCard.begin() + idxPublicCard, tempPublicCard);
    }else{
        dfs(numRound - 1);
    }
    rivalDeck.pop_back();
    rivalHandCard.insert(rivalHandCard.begin() + idxRivalHandCard, tempRivalCard);
}
int maxMyScore = 0, maxRivalScore = 0;
void dfs(int numRound){
    if(numRound == 0){
        int myScore = calScore(myDeck);
        int rivalScore = calScore(rivalDeck);
        if(myScore > maxMyScore){
            maxMyScore = myScore;
            maxRivalScore = rivalScore;
        }else if(myScore == maxMyScore && rivalScore < maxRivalScore){
            maxRivalScore = rivalScore;
        }
        return;
    }
    bool haveSameColorCard = false;
    for(int i = 0; i < myHandCard.size(); ++i){
        string tempMyHandCard = myHandCard[i];
        myHandCard.erase(myHandCard.begin() + i);
        myDeck.push_back(tempMyHandCard);
        for(int j = 0; j < publicCard.size(); ++j){
            if(color[tempMyHandCard] == color[publicCard[j]]){
                haveSameColorCard = true;
                string tempPublicCard = publicCard[j];
                publicCard.erase(publicCard.begin() + j);
                publicCard.push_back(card[idxPublic++]);
                myDeck.push_back(tempPublicCard);
                rivalRound(numRound);
                idxPublic--;
                publicCard.pop_back();
                myDeck.pop_back();
                publicCard.insert(publicCard.begin() + j, tempPublicCard);
            }
        }
        myDeck.pop_back();
        myHandCard.insert(myHandCard.begin() + i, tempMyHandCard);
    }
    if(haveSameColorCard == false){
        for(int i = 0; i < myHandCard.size(); ++i){
            string tempMyHandCard = myHandCard[i];
            myHandCard.erase(myHandCard.begin() + i);
            myDeck.push_back(tempMyHandCard);
            rivalRound(numRound);
            myDeck.pop_back();
            myHandCard.insert(myHandCard.begin() + i, tempMyHandCard);
        }
    }
}
int main(){
    cin >> numCardForPlayer >> numCardForPublic >> score;
    numCardTotal = numCardForPlayer * 4 + numCardForPublic;
    for(int i = 0; i < numCardTotal; ++i){
        char type;
        cin >> card[i] >> type;
        color[card[i]] = type;
    }
    cin >> numCombine;
    for(int i = 0; i < numCombine; ++i){
        int num;
        cin >> num >> combine[i].score;
        for(int j = 0; j < num; ++j){
            string tempCard;
            cin >> tempCard;
            combine[i].cards.push_back(tempCard);
        }
        sort(combine[i].cards.begin(), combine[i].cards.end());
    }
    idxPublic = 0;
    while(myHandCard.size() < numCardForPlayer || publicCard.size() < numCardForPublic){
        if(myHandCard.size() < numCardForPlayer){
            myHandCard.push_back(card[idxPublic++]);
            rivalHandCard.push_back(card[idxPublic++]);
        }
        if(publicCard.size() < numCardForPublic){
            publicCard.push_back(card[idxPublic++]);
        }
    }
    sort(rivalHandCard.begin(), rivalHandCard.end());
    dfs(numCardForPlayer);
    cout<< maxMyScore << " " << maxRivalScore << endl;
    return 0;
}

原文地址:https://www.cnblogs.com/vinnson/p/10844992.html

时间: 2024-10-10 19:03:30

【编程训练-考研上机模拟】综合模拟1-2019浙大上机模拟(晴神)的相关文章

【编程训练-考研上机模拟】综合模拟2-2019浙大上机模拟(晴神)

A - next[i] Problem Description 在字符串匹配的KMP算法中有一个重要的概念是next数组,求解它的过程让不少同学伤透了心.next数组的直接语义其实是:使"长度为L的前缀"与"长度为L的后缀"相同的最大L,且满足条件的前后缀不能是原字符串本身. 例如对字符串"ababa"来说,长度为1的前缀与后缀都是"a",它们相同:长度为2的前缀与后缀分别是"ab"和"ba&qu

2019浙大计算机考研机试模拟赛(2)——概念专题

题目链接   引用自晴神OJ A - 边覆盖 B - 极大独立集 C - 稳定婚姻问题 D - 笛卡尔树 没赶得上全程的比赛,就做了两道,后面两道以后有时间再补.两道都是概念题,比较基础~ 以下是题解 A - 边覆盖 Case Time Limit: 200 MS (Others) / 400 MS (Java)       Case Memory Limit: 256 MB (Others) / 512 MB (Java) Accepted: 199      Total Submission

HTTP的请求和相应以及php实现模拟、curl扩展的使用来模拟访问

1.处理不同的图片格式 针对图片处理的公共类兼容多种图片类型的处理. 只要使用不同类型的图片使用不同的imagecreatefrom类型即可实现. [重点!!!] [php实现网络编程] 2.HTTP请求协议[HTTP权威指南已经看了,但是还没有深刻的认识] HTTP用于规范b/s架构中,浏览器和服务器之间信息数据交换的规则.[超文本传输协议对应的(超文本标记语言和数据)] 浏览器和服务器之间建立的TCP连接[连接部分需要注意:三次握手已经不说.持久连接本身占用的资源问题(持久连接保证了HTTP

(编程训练)再回首,数据结构——二叉树的前序、中序、后序遍历(非递归)

最近在复习数据结构,顺便看看大一的时候写的代码,看完之后比当初有了更加深刻的体会. 希望这些能提供给初学者一些参考. 在VC++6.0下可运行,当初还写了不少注释. 可以和(编程训练)再回首,数据结构--二叉树的前序.中序.后序遍历(递归)对比着看 [问题描述] 根据顺序存储结构建立二叉树的二叉链表,并对二叉树进行先序.中序.后序遍历. [基本要求] ·功能:根据顺序存储结构建立二叉树的二叉链表,并进行先序.中序.后序遍历. ·输入:输入二叉树的顺序存储. ·输出:二叉树的先序.中序.后序遍历序

C语言编程入门——综合练习(四)上机考试题

这份程序是我们学院C语言上机考试题库中的部分题,由我同学总结,并共享给大家.(Word中的程序,排版有些问题,还请见谅) 求n个(项)数据之和或积 //求n个数据的和(或积) #include <stdio.h> int main() { int a[100];  int i = 0; int n; printf("此程序将实现累和还有累积的功能,请输入项数\n"); scanf("%d", &n); printf("请输入各项\n&q

2019.10.24模拟赛赛后总结

本文原创,如果有不到位的地方欢迎通过右下角的按钮私信我! A.Icow Player 题目描述 被无止境的农活压榨得筋疲力尽后,Farmer John打算用他在MP3播放器市场新买的iCow来听些音乐,放松一下.FJ的iCow里存了N(1 <= N <= 1,000)首曲子,按1..N依次编号.至于曲子播放的顺序,则是按一个Farmer John自己设计的算法来决定: * 第i首曲子有一个初始权值R_i(1 <= R_i <= 10,000). * 当一首曲子播放完毕,接下来播放的

两个栈模拟一个队列和两个队列模拟一个栈

此为网易的一道笔试题.到时候秀逗,不知所云.后来研究之后记录下,以备以后经常翻阅. 栈:先进后出 push和pop 队列:先进先出 offer和poll (1)两个栈模拟一个队列 即将先进后出实现先进先出.比较容易理解,只要所有数据先往一个栈里push,然后将该栈中的数据依次pop出来再push进第二个队列,则顺序自然颠倒过来了,则每次pop是从第二个队列中取数据. import java.util.*; public class StackQueue{ private Stack<Intege

C++ 字符串编程训练1

最近又到了找工作的时间,所以想每天抽点时间出来对编程进行相关训练.C++字符串是一个很重要的知识点,采用STL.算法等C++优于C的方面,能够使问题解决起来更加轻松.以下程序都是自己写的,可能有些地方时间效率.空间效率不高,所以希望大家能够多多讨论交流,互相提升. 题目:删除子串 说明:给定两个形参str和substr,其中str为源字符串,substr为需要删除的子串,如果str中包含substr,则将其删除并输出新的字符串,否则输出源字符串. void delete_substr(strin

数据结构和算法之栈和队列一:两个栈模拟一个队列以及两个队列模拟一个栈

今天我们需要学习的是关于数据结构里面经常看到的两种结构,栈和队列.可以说我们是一直都在使用栈,比如说在前面递归所使用的的系统的栈,以及在链表倒序输出时介绍的自定义栈类Stack和使用系统的栈进行递归.那么,在这里我们就讲述一下这两个比较具有特色的或者说关系比较紧密的数据结构之间的互相实现问题. 一:两个栈模拟实现一个队列: 栈的特点是先进后出,然而队列的特点是先进先出. public class Queen(Stack s1,Stack s2){ //实现插入的方法 public void ad