某天,LX和ZH因为一道构造题的做法争执不下,无法说服对方。为了决定谁对谁错(或许两人都错了),机智的HN建议采用最朴素和最公平的方法——石头剪刀布游戏。LX很害羞不愿意让教练看到比赛结果,所以在比赛结束后悄悄离开了。然而,好奇心旺盛的HN向ZH询问了比赛的过程和结果。ZH仅仅告诉了HN他的出拳顺序以及比赛的比分。HN并不想在这种无意义的事情上浪费时间(实际上他也不会解决),因此希望你来帮他确定是否存在一种LX的出拳顺序能够使比赛结果符合ZH所说的比分。
"shitou"代表石头,"jiandao"代表剪刀,"bu"代表布
赢一局加两分,输一局扣一分,平局不加分
(本题的“字典序”可以类比字符串的字典序)
输入格式:
输入为两行,第一行为两个整数x,y分别代表LX和ZH的最终得分,第二行为ZH的出拳顺序 s 。
(∣x∣<=1e9,∣y∣<=1e9,∣s∣<=10)
输出格式:
若是有满足题意的则输出其中字典序最小的一种LX的合法出拳顺序;
若是一种也没有则说明zh在骗人,则输出"zh is a pianzhi"。
输入样例1:
2 -1
shitou jiandao bu end
输出样例1:
bu jiandao bu
输入样例2:
2 0
shitou jiandao bu end
输出样例2:
zh is a pianzhi
源代码:
#include<bits/stdc++.h>
using namespace std;
map<string,int>mp1={{"jiandao",0},{"shitou",1},{"bu",2}};
map<int,string>mp2={{0,"jiadao"},{1,"shitou"},{2,"bu"}};
vector<string>ans,tmp;
vector<int>v;
int x,y;
void dfs(int idx,int a,int b)
{
if(idx>=v.size())
{
if(x==a&&b==y)
{
for(int i=0;i<tmp.size();i++)
{
if(ans.size()==0||tmp[i]<ans[i])
{
ans=tmp;
return;
}
if(tmp[i]>ans[i])
{
break;
}
}
}
return;
}
int x=v[idx];
tmp.push_back(mp2[x]);
dfs(idx+1,a,b);
tmp.pop_back();
tmp.push_back(mp2[(x+1)%3]);
dfs(idx+1,a+2,b-1);
tmp.pop_back();
tmp.push_back(mp2[(x+2)%3]);
dfs(idx+1,a-1,b+2);
tmp.pop_back();
}
int main()
{
cin>>x>>y;
while(1)
{
string s;
cin>>s;
if(s=="end")break;
v.push_back(mp1[s]);
}
dfs(0,0,0);
if(ans.size()==0)cout<<"zh is a pianzhi"<<endl;
else{
for(int i=0;i<ans.size();i++)
{
if(i)cout<<" ";
cout<<ans[i];
}
cout<<endl;
}
}
思路分析和问题:
开始思路确实是dfs,但是由于是string形式的,所以在dfs里面绕了好久,主要卡在如何判断谁赢谁输的问题,题解给出的map1,map2解决这个问题,直接输赢的顺序来排,直接就可以得到按照顺序来判断输赢,至于结束dfs的条件部分,有一些优化,直接如果tmp比ans小,直接更新ans,结束这次的dfs,没有这步可能会段错误(我是这样的)。
本题确实也开拓了思路,map的灵活应用。