不知不觉,近两年的ccf前两题都刷完了呢
大概总结一下,第一题就是个简单水题,热身签到
第二题是个简单模拟,多数是对数据或自创数据结构排序的考察,细心分析内部关系就好了
第三题就是个大模拟了,一般条件考虑还比较多,细心才能成大事
这次就来三道大模拟吧
三道题都是个字符串处理题,string,用getline读取,那么先关一下cin同步吧
ios::sync_with_stdio(false);
201703-3 Markdown
思路:字符串处理,根据每行首元素判断标题、段落和无序列表,然后分别按要求处理
对于下划线和链接,需要单独写个函数特判,下划线是个全局变量,因为其嵌套性很强,而链接中很可能还要套链接,于是写成递归吧
这题细节点很多,6次尝试后终于拿了满分
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
bool down;
string dealstring(string s)
{
int len = s.size();
string re = "";
for(int pos=0;pos<len;pos++)
{
if(s[pos] == '_')
{
if(down)
{
down = false;
re += "</em>";
}
else
{
down = true;
re += "<em>";
}
continue;
}
if(s[pos] == '[')
{
pos++;
int st = pos;
int slen = 1;
while(s[pos]!= ']')
{
slen++;
pos++;
}
string text = dealstring(s.substr(st,slen-1));
pos++;
pos++;
st = pos;
slen = 1;
while(s[pos]!= ')')
{
slen++;
pos++;
}
string link = dealstring(s.substr(st,slen-1));
re += "<a href=\"" + link + "\">" + text + "</a>";
continue;
}
re += s[pos];
}
return re;
}
int main()
{
string line;
bool star = false;
bool paragraph = false;
//freopen("in3.txt","r",stdin);
down = false;
while(getline(cin,line))
{
int len = line.size();
if(len==0)
{
if(star)
{
star = false;
cout << "</ul>" << endl;
}
if(paragraph)
{
paragraph = false;
cout << "</p>" << endl;
}
continue;
}
if(line[0]=='#')
{
if(star)
{
star = false;
cout << "</ul>" << endl;
}
if(paragraph)
{
paragraph = false;
cout << "</p>" << endl;
}
int num = 1;
int pos = 1;
while(pos <= len)
{
if(line[pos]=='#')
{
num++;
}
else if(line[pos]!=' ')
{
break;
}
pos++;
}
cout << "<h" << num << ">";
cout << dealstring(line.substr(pos,len-pos));
cout << "</h" << num << ">" << endl;
}
else if(line[0]=='*')
{
if(paragraph)
{
paragraph = false;
cout << "</p>" << endl;
}
if(!star)
{
star = true;
cout << "<ul>" << endl;
}
cout << "<li>";
int pos = 1;
while(pos <= len)
{
if(line[pos]!=' ')
{
break;
}
pos++;
}
cout <<dealstring(line.substr(pos,len-pos));
cout << "</li>" << endl;
}
else
{
if(star)
{
star = false;
cout << "</ul>" << endl;
}
if(!paragraph)
{
paragraph = true;
cout << "<p>";
}
else
{
cout << endl;
}
int pos = 0;
while(pos <= len)
{
if(line[pos]!=' ')
{
break;
}
pos++;
}
cout << dealstring(line.substr(pos,len-pos));
}
}
if(star)
{
star = false;
cout << "</ul>" << endl;
}
if(paragraph)
{
paragraph = false;
cout << "</p>" << endl;
}
return 0;
}
/*
# Heading
## Sub-heading
Paragraphs are seperated
by a blank line.
Text attributes _italic_.
Bullet list:
* apples
* oranges
* pears
A [link](http://example.com).
*/
201612-3 权限查询
思路:这题主要就是stl的嵌套,map套map,还是思路问题,大脑一定要清晰
对于第一个特权,既然后面限定特权合法,那么完全没用啊,直接读进来就好了,getline读缓冲区,时时输出检查,这题还挺顺利,差点一发ac,就是没注释freopen有点坑了
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 1e5+10;
map<string,map<string,int> > privilege;
int main()
{
//cout << privilege["5"] << "*"<<endl;
//freopen("in.txt","r",stdin);
ios::sync_with_stdio(false);
privilege.clear();
int p;
cin >> p;
for(int i=0;i<=p;i++)
{
string temp;
getline(cin,temp);
}
int r;
cin >> r;
for(int i=0;i<=r;i++)
{
string temp;
getline(cin,temp);
int len = temp.size();
if(len == 0)
{
continue;
}
//cout << temp << "*&^" << endl;
int pos;
string role;
temp += " ";
len++;
for(pos=0;pos<len;pos++)
{
if(temp[pos] == ' ')
{
break;
}
}
role = temp.substr(0,pos);
pos += 3;
string pri;
while(pos<len)
{
//cout << pos << "$$$" << endl;
bool nex = false;
int posstop;
for(posstop=pos;posstop<len;posstop++)
{
if(temp[posstop] == ':')
{
break;
}
else if(temp[posstop] == ' ')
{
nex = true;
break;
}
}
pri = temp.substr(pos,posstop-pos);
//cout << pri << "%^&&^%" << endl;
int ran = -1;
if(nex)
{
nex = false;
}
else
{
posstop++;
ran = temp[posstop]-'0';
posstop++;
}
//cout << pri << "%^&&^%" << ran << endl;
if((privilege.find(role)!=privilege.end())&&(privilege[role].find(pri)!=privilege[role].end()))
{
if(privilege[role][pri]<ran)
{
privilege[role][pri] = ran;
}
}
else
{
privilege[role][pri] = ran;
}
pos = posstop+1;
}
}
/*map<string,map<string,int> > :: iterator it = privilege.begin();
map<string,int> :: iterator itt;
for(;it!=privilege.end();it++)
{
cout << (it->first) <<"*"<< endl;
for(itt=(it->second).begin();itt!=(it->second).end();itt++)
{
cout << (itt->first) << "#" << (itt->second) << endl;
}
}*/
int u;
cin >> u;
for(int i=0;i<=u;i++)
{
string temp;
getline(cin,temp);
int len = temp.size();
if(len == 0)
{
continue;
}
string person;
int pos;
temp += " ";
len++;
for(pos=0;pos<len;pos++)
{
if(temp[pos] == ' ')
{
break;
}
}
person = temp.substr(0,pos);
pos += 3;
string rr;
while(pos<len)
{
int posstop;
for(posstop=pos;posstop<len;posstop++)
{
if(temp[posstop] == ' ')
{
break;
}
}
rr = temp.substr(pos,posstop-pos);
//cout << pri << "%^&&^%" << endl;
map<string,int> :: iterator pit = privilege[rr].begin();
for(;pit!=privilege[rr].end();pit++)
{
if((privilege.find(person)!=privilege.end())&&(privilege[person].find(pit->first)!=privilege[person].end()))
{
if(privilege[person][pit->first]<(pit->second))
{
privilege[person][pit->first]=(pit->second);
}
}
else
{
privilege[person][pit->first]=(pit->second);
}
}
pos = posstop+1;
}
}
/*map<string,map<string,int> > :: iterator it = privilege.begin();
map<string,int> :: iterator itt;
for(;it!=privilege.end();it++)
{
cout << (it->first) <<"*"<< endl;
for(itt=(it->second).begin();itt!=(it->second).end();itt++)
{
cout << (itt->first) << "#" << (itt->second) << endl;
}
}*/
int q;
cin >> q;
for(int i=0;i<=q;i++)
{
string temp;
getline(cin,temp);
int len = temp.size();
if(len == 0)
{
continue;
}
int pos;
temp += " ";
len++;
string sperson;
for(pos=0;pos<len;pos++)
{
if(temp[pos] == ' ')
{
break;
}
}
sperson = temp.substr(0,pos);
pos ++;
string pri;
bool nex = false;
int posstop;
for(posstop=pos;posstop<len;posstop++)
{
if(temp[posstop] == ':')
{
break;
}
else if(temp[posstop] == ' ')
{
nex = true;
break;
}
}
pri = temp.substr(pos,posstop-pos);
int ran = -1;
if(!nex)
{
posstop++;
ran = temp[posstop]-'0';
}
if(privilege.find(sperson) != privilege.end())
{
if(privilege[sperson].find(pri)!=privilege[sperson].end())
{
if(ran==-1)
{
if(privilege[sperson][pri] == ran)
{
cout << "true" << endl;
}
else
{
cout << privilege[sperson][pri] << endl;
}
}
else
{
if(privilege[sperson][pri]>=ran)
{
cout << "true" << endl;
}
else
{
cout << "false" << endl;
}
}
}
else
{
cout << "false" << endl;
}
}
else
{
cout << "false" << endl;
}
}
//cout << p << r << u << q << endl;
return 0;
}
201604-3 路径解析
思路:这题也是满满的坑点啊
首先,对于合法路径,一定是由‘/’和名称组成,且名称中不含‘/’,那么利用压栈的思想,直接记录路径,最后自己生成标准格式,这样就免去了矫正格式中的大量细节
这题主要两个坑点就是‘.’,这个不起眼的点号,不仅仅可以表示当前路径,上一路径,也可以作为文件名,这个确实很意外,比较难考虑到,因为题目中只说了名称不为‘.’和‘..’,没说不能作为文件名的一部分
其他还有就是并不一定以‘.’开头才是相对路径,一切不以‘/’开头的路径均为相对路径,其实这个题目中说的很清楚,但很容易相当然就忽略误解了
最后就是空行了,这个一不小心就容易被忽略了,一不小心也就容易被改动,还是细心问题
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 1010;
vector <string> contem;
int clen;
void correctaddress(string s)
{
stack <string> address;
while(!address.empty())
{
address.pop();
}
stack <string> prin;
while(!prin.empty())
{
prin.pop();
}
int len = s.size();
if(s[0]!='/'||s.empty())
{
for(int i=0;i<clen;i++)
{
address.push(contem[i]);
}
}
if(!s.empty())
{
s += '/';
}
string addr;
addr.clear();
//bool name = false;
for(int pos=0;pos<len;pos++)
{
if(s[pos]=='/')
{
if(!addr.empty())
{
if(addr == "..")
{
if(!address.empty())
{
address.pop();
}
}
else if(addr != ".")
{
address.push(addr);
}
addr.clear();
}
//name = false;
}
/*else if(s[pos]=='.'&&(!name))
{
if(s[pos+1]=='/')
{
continue;
}
if(s[pos+1]=='.'&&s[pos+2]=='/')
{
if(!address.empty())
{
address.pop();
}
}
else
{
addr += s[pos];
//name = true;
}
}*/
else
{
addr += s[pos];
//name = true;
}
}
if(!addr.empty())
{
if(addr == "..")
{
if(!address.empty())
{
address.pop();
}
}
else if(addr != ".")
{
address.push(addr);
}
addr.clear();
}
while(!address.empty())
{
string str = address.top();
prin.push(str);
address.pop();
}
if(prin.empty())
{
cout << "/" << endl;
}
else
{
while(!prin.empty())
{
string str = prin.top();
cout << "/" << str;
prin.pop();
}
cout << endl;
}
return ;
}
int main()
{
//freopen("in.txt","r",stdin);
ios::sync_with_stdio(false);
int p;
cin >> p;
string ori;
getline(cin,ori);
getline(cin,ori);
contem.clear();
int len = ori.size();
string addr;
addr.clear();
for(int pos=0;pos<len;pos++)
{
if(ori[pos]=='/')
{
if(!addr.empty())
{
contem.push_back(addr);
clen++;
addr.clear();
}
}
else
{
addr += ori[pos];
}
}
if(!addr.empty())
{
contem.push_back(addr);
clen++;
addr.clear();
}
/*for(int i=0;i<(int)(contem.size());i++)
{
cout << contem[i] <<"*" << clen<< endl;
}*/
while(p--)
{
string now;
getline(cin,now);
correctaddress(now);
}
return 0;
}
就此,近两年的第三道大模拟也全部刷完了,这周离出发还有7天,加油!
文章地址:http://blog.youkuaiyun.com/owen_q/article/details/78237560