路径解析:
给定当前目录及路径中部分特殊字符或字符串所表示的含义,对输入的每一个路径进行正规化操作(将相对路径即从当前目录开始构建的路径转化为绝对路径即从根目录开始构建的路径)。
一开始看到这道题的时候,被样例给出的结构所吓到,觉得这个题可能有点复杂。但仔细读完题之后发现这道题很简单。无需像想象中的那样还要储存文件结构,只需要针对每一种路径的具体情况进行处理即可。由绝对路径格式我们可以知道,绝对路径中最为重要的是路径中的文件目录。那我们不妨就只对文件目录进行处理,利用相对路径中的文件目录与特殊字符将绝对路径中的文件目录全部找出来,就可以轻松构造绝对路径。按照题目要求,遇到‘…’就返回上一级目录(也就是将删除路径中最后一个目录),遇到‘.’就忽略,遇到‘/’就判断是否存在文件目录,存在即保存后继续处理,不存在则直接继续处理;若是开头为/则从根目录开始处理,反之则从当前目录开始处理,即将到达当前目录路径中的所有文件目录先保存在绝对路径中,然后再根据相对路径中的字符串进行处理。
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int n,sum,t,begin;
cin>>n;
string s,s1;
string a[10010],b[10010];
cin.get();
getline(cin, s);
s=s+'/';
for (int i=1;i<s.length();i++)
{
if (s[i]=='/')
{
if (s1.length()>0)
{ a[sum]=s1;
sum++;}
s1="";
}
else
{s1=s1+s[i];}
}
for (int k=0;k<n;k++)
{
getline(cin, s);
s=s+'/';
s1="";
if (s[0]=='/')
{ t=0;
begin=1;}
else
{ t=sum;
for (int i=0;i<sum;i++)
b[i]=a[i];
begin=0;}
for (int i=begin;i<s.length();i++)
{ if (s[i]=='/')
{ if (s1=="..")
{if(t>0) t--;}
else if (s1=="."){}
else if(s1.length()>0)
{ b[t]=s1;
t++;}
s1="";}
else{s1=s1+s[i];}}
if (t==0) cout<<"/";
for (int i=0;i<t;i++)
cout<<"/"<<b[i];
cout<<endl;
}
return 0;
}
炉石传说
定义以下几种操作类型:
- summon position attack health :当前玩家在位置position召唤一个生命值为health、攻击力为attack的随从。其中position是一个 1 到 7 的整数,表示召唤的随从出现在战场上的位置,原来该位置及右边的随从都将顺次向右移动一位。
- attack attacker defender:当前玩家的角色attacker攻击对方的角色 defender。attacker是 1 到 7 的整数,表示发起攻击的本方随从编号,defender是 0 到 7 的整数,表示被攻击的对方角色,0 表示攻击对方英雄,1 到 7 表示攻击对方随从的编号。
- end:当前玩家结束本回合。
给定操作数与操作,给出最后的胜负关系与双方的情况。
summon操作:将当前玩家位置大于等于position的生命值与攻击值数据全部右移一位(模拟随从向右移动),更新position位置的生命值与攻击值,同时随从数量加一。
attack:当前玩家attacker位置的随从攻击对方defender位置的随从。双方生命值均减掉对方攻击值。生命值小于等于0说明随从死亡,从对应玩家的随从信息中将该随从删除(将该位置右边的所有位置数据向左移动一位,同时随从数量减一)。这里需要注意的是,攻击方可以用攻击玩家,但不可以用玩家进行攻击。也就是说,一方的攻击阶段只有另一方生命值可能小于等于0,如果小于等于0,另一方玩家死亡,游戏自动结束,输出胜负情况与各方局面,反之游戏继续。
end:转换游戏方
#include<iostream>
#include<string>
using namespace std;
int main()
{
int n;
cin>>n;
int people=0;
int a[2][8],h[2][8],sum[2]={0};
h[0][0]=h[1][0]=30;
a[0][0]=a[1][0]=0;
string s;
int pos,pos1,pos2;
for(int i=0;i<n;i++)
{
cin>>s;
if(s=="summon")
{ cin>>pos;
for(int i=sum[people];i>=pos;i--)
{
h[people][i+1]=h[people][i];
a[people][i+1]=a[people][i];}
cin>>a[people][pos]>>h[people][pos];
sum[people]++;}
if(s=="attack")
{ cin>>pos1>>pos2;
h[people][pos1]=h[people][pos1]-a[(people+1)%2][pos2];
h[(people+1)%2][pos2]=h[(people+1)%2][pos2]-a[people][pos1];
if(h[people][pos1]<=0)
{
for(int j=pos1;j<sum[people];j++){
h[people][j]=h[people][j+1];
a[people][j]=a[people][j+1];}
sum[people]--;
}
if(h[(people+1)%2][pos2]<=0&&pos2!=0)
{
for(int j=pos2;j<sum[(people+1)%2];j++){
h[(people+1)%2][j]=h[(people+1)%2][j+1];
a[(people+1)%2][j]=a[(people+1)%2][j+1];}
sum[(people+1)%2]--;
}
if(h[(people+1)%2][pos2]<=0&&pos2==0) break;
}
if(s=="end")
{people=(people+1)%2;}
}
if(h[0][0]>0&&h[1][0]>0) cout<<"0"<<endl;
else if(h[0][0]<=0) cout<<"-1"<<endl;
else cout<<"1"<<endl;
cout<<h[0][0]<<endl;
cout<<sum[0]<<" ";
for(int i=1;i<=sum[0];i++)
{ cout<<h[0][i]<<" ";}
cout<<endl;
cout<<h[1][0]<<endl;
cout<<sum[1]<<" ";
for(int i=1;i<=sum[1];i++)
{cout<<h[1][i]<<" ";}
cout<<endl;
return 0;
}
元素选择器
给定一个格式化文档和若干个选择器,给出每次所选择的内容。
标签选择器:找出文档中所有标签符合要求的文档。由于标签大小写不敏感,我们需要将所有标签中的字母都转换成小写字母才可以找出所有符合要求的文档。
id选择器:根据id直接进行选择即可。
后代选择器:格式A B。表示选择满足选择器B且有祖先元素满足选择器A的所有元素。这里涉及到两个问题:如何找到一个元素的祖先元素,以及对于多级选择器来说怎样叫祖先元素满足选择器A。我们一个一个解决:如何找到祖先元素,由题意可知,标签之前的缩进表示元素之间的包含关系,以两个小数点符号表示一级缩进,则某一元素的父亲定是比其小一级在其之前最近的元素,我们按照这个结论来找,就能找到每一个元素的所有祖先元素。那又如何让祖先元素满足选择器A呢,要知道,多级选择器中A并不唯一。我们不妨这样想:假设A B C为一个多级选择器,我们如何找到满足要求的目录呢?毋庸置疑首先先找C,那么找完C之后对于A和B有没有要求呢?答案是有的。如果我们先找到了A,祖先选择器满足A了,可是此时并没有满足B C,这就意味着没有找到。也就是说,我们要找到满足要求的目录,对于要求必须从后向前一步一步满足。也就是说,当我们找到满足C的元素后,我们要先找其祖先元素中是否有满足B的元素,找到了才能继续寻找满足A的元素。只有在这种情况下找到了目录才是符合要求的目录。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
struct nameNode{
int level;
string p,id;
};
string to_lower(string s) {
for(int i=0;i<s.size();i++) {
if('A'<=s[i]&&s[i]<='Z') {
s[i]+=32;}}
return s;
}
vector<nameNode> a;
vector<string> st;
vector<int> ans;
int main(){
int n,m;
cin>>n>>m;
getchar();
string s;
nameNode b;
for(int i=0;i<n;i++){
b.id="";
b.p="";
getline(cin,s);
int j=0;
while(s[j]=='.'){j++;}
b.level=(j+1)/2;
while(s[j]!=' '&&j<s.length()){if(s[j]<='Z'&&s[j]>='A'){s[j]+=32;}b.p=b.p+s[j];j++;}
j++;
while(j<s.length()){b.id=b.id+s[j];j++;}
a.push_back(b);
}
for(int k=0;k<m;k++){
st.clear();
ans.clear();
getline(cin,s);
string s1="";
for(int i=0;i<s.length();i++){
if(s[i]==' '){if(s1[0]!='#'){s1=to_lower(s1);}st.push_back(s1);s1="";}
else {s1=s1+s[i];}}
if(s1[0]!='#'){s1=to_lower(s1);}
st.push_back(s1);
if(st.size()==1){
for(int i=0;i<a.size();i++){
if(s1==a[i].id||to_lower(s1)==a[i].p){ans.push_back(i+1);}
}
}
else if(st.size()>1){
string sp=st[st.size()-1];
for(int i=0;i<a.size();i++){
if(sp!=a[i].id&&sp!=a[i].p){continue;}
int index=st.size()-2;
int level=a[i].level;
for (int k=i; k>=0&&index>=0;k--) {
if(a[k].level<level) {
level=a[k].level;
if (st[index]==a[k].id||st[index]==a[k].p){
index--;}
}
}
if(index<0){ans.push_back(i+1);}
}}
cout<<ans.size();
for(int i=0;i<ans.size();i++){
cout<<" "<<ans[i];
}
cout<<endl;
}
return 0;
}