问题描述:
给定一个短字符串(不含空格),再给定若干字符串,在这些字符串中删除所含有的短字符串。
输入:
输入只有1组数据。
输入一个短字符串(不含空格),再输入若干字符串直到文件结束为止。
输出:
删除输入的短字符串(不区分大小写)并去掉空格,输出。
样例输入:
in
#include
int main()
{
printf(" Hi ");
}
样例输出:
#clude
tma()
{
prtf(“Hi”);
}
注:将字符串中的In,IN,iN,in删除
思路:
find()
、erase()
函数删除所有目标字符串,由于题目要求是不区分大小写,所以该想法难以实现,因为如果目标字符串长度为n,大小写组合有 2 n 2^n 2n种,时间复杂度很高。int pos = ans.find(temp);
while (pos != ans.npos) //如果没找到,返回一个特别的标志,C++用npos表示
{
ans.erase(pos, 2);
pos = ans.find(temp);
}
#include
#include
#include
using namespace std;
char temp[1000];
char c[1000];
char a[1000];
int main()
{
cin >> temp;
int len = strlen(temp);
//将目标字符串统一为小写
for (int i = 0; i < len; i++)
{
temp[i] = tolower(temp[i]);
}
int i = 0;
int x = 0;
//注意:cin.get()将缓冲区的‘\n’取走,否则c[0]='\n'
cin.get();
cin.getline(c, 10000, EOF);
while (i<strlen(c))
{
//将统一为小写之前的字符串存在数组a中
a[x] = c[i];
c[i] = tolower(c[i]);
if (c[i] == ' ') x--;
int k;
int j = i;
for (k = len - 1; k >= 0; k--)
{
if (c[j] != temp[k])
break;
j--;
}
//注意:正常结束循环跳出时 k=-1 !!!
if (k == -1)
x = x - len;
i++;
x++;
}
cout << a;
return 0;
}
有一点小疑问,为什么输出a会换行??
#include
#include
#include
using namespace std;
int main()
{
string del, rep,lrep;
int index, k;
getline(cin, del);
for (int i = 0; i < del.length(); i++) {
del[i] = tolower(del[i]);
}
while (getline(cin, rep))
{
lrep = "";
index = 0;
for (int i = 0; i < rep.length(); i++)
lrep += tolower(rep[i]);
while (lrep.find(del, index) != string::npos)
{
k = lrep.find(del, index);
lrep.erase(k, del.length());
rep.erase(k, del.length());
index = k;
}
index = 0;
while (lrep.find(" ", index) != string::npos)
{
k = lrep.find(" ", index);
lrep.erase(k, 1);
rep.erase(k, 1);
index = k;
}
cout << rep << endl;
}
return 0;
}
问题描述:
对于一个字符串,将其后缀子串进行排序,例如grain
其子串有:
grain
rain
ain
in
n
然后对各子串按字典顺序排序,即:
ain,grain,in,n,rain、
输入:
每个案例为一行字符串。
输出
将子串排序输出
样例输入:
grain
banana
样例输出:
ain
grain
in
n
rain
a
ana
anana
banana
na
nana
思路:用STL中的set容器,元素插入后是有序的,通过迭代器遍历就能得到子串的字典序排列。
代码如下:
#include
#include
#include
using namespace std;
set<string> st;
int main()
{
string s;
while(cin>>s)
{
st.clear();
int len = s.length();
int i = 1;
st.insert(s);
//每次删除字符串首的一个字符,得到一个子串
//注意循环条件
while(i<len)
{
s.erase(0, 1);
st.insert(s);
i++;
}
//只能通过迭代器遍历set
for(set<string>::iterator it=st.begin();it!=st.end();it++)
{
cout<<*it<<endl;
}
}
}
题目描述:
有n个城市m条道路(n<1000, m<10000),每条道路有个长度,请找到从起点s到终点t的最短距离和经过的城市名。
输入:
输入包含多组测试数据。
每组第一行输入四个数,分别为n,m,s,t。
接下来m行,每行三个数,分别为两个城市名和距离。
输出:
每组输出占两行。
第一行输出起点到终点的最短距离。
第二行输出最短路径上经过的城市名,如果有多条最短路径,输出字典序最小的那条。若不存在从起点到终点的路径,则输出“can’t arrive”。
样例输入:
3 3 1 3
1 3 3
1 2 1
2 3 1
样例输出:
2
1 2 3
思路:前几天复习了最短路径,因为此题要输出经过的城市,所以用采用dfs遍历,找出所有可达的路径,输出最短的那一条。
#include
using namespace std;
int e[1000][1000];
int book[1000] = {0};//book标记某个城市是否走过
int flag[1000] = {0};//flag标记某个城市是否在可达路径中,最终得到最短可达路径经过的城市
int n, m;
int s, t;
int INF = INT32_MAX;
int Min = INF;
void dfs(int cur, int dis);
int main()
{
int i, j;
while (cin >> n >> m >> s >> t)
{
//注意将Min,book,flag初始化!
Min = INF;
for (int i = 1; i <= n; i++)
{
book[i] = 0;
flag[i] = 0;
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
if (i == j)
e[i][j] = 0;
else
e[i][j] = INF;
}
for (int k = 0; k < m; k++)
{
cin >> i >> j;
cin >> e[i][j];
}
book[s] = 1;
dfs(s, 0);
if (Min < INF)
cout << Min << endl;
else
cout << "can't arrive" << endl;
for (int i = 1; i <= n;i++)
{
if(flag[i]==1)
cout << i<< " ";
}
cout << endl;
}
return 0;
}
void dfs(int cur, int dis)
{
//剪枝
if(dis>INF)
return;
if (cur == t)
{
//更新最短路径
if(dis<Min)
{
Min = dis;
for (int i = 1; i <= n;i++)
flag[i] = book[i];
}
return;
}
else
{
for (int i = 1; i <= n;i++)
{
if(book[i]==0&&e[cur][i]>0&&e[cur][i]!=INF)
{
book[i] = 1;
dfs(i, dis + e[cur][i]);
book[i] = 0;
}
}
}
}
后来发现该解法只能从1~n依次输出经过的点,并不能按序输出路径上的点,想当然了,考虑不全面……借鉴https://blog.csdn.net/jinixin/article/details/52247763的思路,得到以下代码。
#include
using namespace std;
void dijsktra();
void Print(int x);
int e[1000][1000];
int n, m, s, t;
int dis[1000];
int INF = 999999999;
int book[1000] = {0};
int Min = INF;
int Path[1000];
int main()
{
int i, j;
while (cin >> n >> m >> s >> t)
{
Min = INF;
for (int i = 1; i <= n; i++)
{
book[i] = 0;
Path[i] = 0;
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
if (i == j)
e[i][j] = 0;
else
e[i][j] = INF;
}
for (int k = 0; k < m; k++)
{
cin >> i >> j;
cin >> e[i][j];
}
for (int i = 1; i <= n; i++)
dis[i] = e[s][i];
book[s] = 1;
dijsktra();
if (dis[t] != INF)
{
cout << dis[t] << endl;
Print(t);
}
else
cout << "can't arrive";
cout << endl;
}
return 0;
}
void dijsktra()
{
int count = 1;
while (count < n)
{
Min = INF;
int j;
for (int i = 1; i <= n; i++)
{
if (book[i] == 0 && dis[i] < Min && dis[i] != INF)
{
Min = dis[i];
j = i;
}
}
book[j] = 1;
for (int i = 1; i <= n; i++)
if (dis[i] > dis[j] + e[j][i])
{
dis[i] = dis[j] + e[j][i];
Path[i] = j;
}
count++;
}
}
void Print(int x)
{
if (x == 0)
cout << s << " ";
else
{
Print(Path[x]);
cout << x << " ";
}
}
问题描述:
略,看输入输出可知~
样例输入:
7
WINNT\SYSTEM32\CONFIG
GAMES
WINNT\DRIVERS
HOME
WIN\SOFT
GAMES\DRIVERS
WINNT\SYSTEM32\CERTSRV\CERTCO~1\X86
样例输出:
GAMES
DRIVERS
HOME
WIN
SOFT
WINNT
DRIVERS
SYSTEM32
CERTSRV
CERTCO~1
X86
CONFIG
思路:以每个目录名作为字符建立一个字典树即可,每个节点的关系可以用map优化。其中m[now][str]=++tot
,now编号相同的文件str即在同一个目录下。对m[now]用迭代器遍历,可得到当前目录文件的字典序排列。
#include
#include
#include
using namespace std;
string t, s;
map<string, int>M[20001];
int tot, n, p, pos;
void pre(int m, int s) { //m:当前编号,s:前导空格
map<string, int>::iterator it;
for (it = M[m].begin(); it != M[m].end(); ++it) {
for (int i = 0; i < s; i++) cout << ' ';
cout << it->first << endl;
pre(it->second, s + 1);
}
}
int main()
{
cin >> n;
while (n--) {
int now = 0; //当前所在树的结点编号
cin >> t;
pos = p = 0; //将'\'作为分隔符依次抽取子串插入树中
while ((p = t.find('\\', p)) != -1) {
s = t.substr(pos, p - pos);
if (!M[now].count(s)) M[now][s] = ++tot;
now = M[now][s];
pos = ++p;
}
s = t.substr(pos);
if (!M[now].count(s)) M[now][s] = ++tot; //处理最后一个文件名
}
pre(0, 0);
return 0;
}
题目描述:
铁路进行列车调度时,常把站台设计成栈式结构的站台,试问:
设有编号为1到n的n辆列车,顺序开入栈式结构的站台,则可能的出栈序列有多少种?
输入
输入包含多组测试数据。每组为一个正整数n(1<=n<=20),表示有n辆列车。
输出
输出可能的出栈序列有多少种。
样例输入
4
3
样例输出
14
5
思路:
if (A == a[B]) //列车A直接开走,不进站
{
A++;
B++;
}
else if (!s.empty() && a[B] == s.top()) //栈不空,并且栈顶元素与目标序列相等,a[B]出站
{
s.pop();
B++;
}
else if (A <= n) //A进站
{
s.push(A); A++;
}
else
{
flag = 1;
break;
}
总的代码如下:
#include
#include
using namespace std;
int a[1000];
bool Judge();
void Perm(int k);
int n;
int Count = 0;
int main()
{
while (cin >> n)
{
Count = 0;
for (int i = 0; i < n; i++)
a[i] = i + 1;
Perm(0);
cout << Count << endl;
}
return 0;
}
void Perm(int k)
//递归产生前缀是a[0:k-1],且后缀是a[k:n]的全排列的所有排列
{
if (k == (n - 1))
{
if (Judge())
Count++;
}
else
{
for (int i = k; i < n; i++)
{
int temp = a[k]; a[k] = a[i]; a[i] = temp;
Perm(k + 1);
temp = a[k]; a[k] = a[i]; a[i] = temp;
}
}
}
bool Judge()
//判断是不是正确的出站序列
{
int A = 1, B = 0;//A是原序列(1-n),B是排序后数组下标
int flag = 0;
stack<int> s; //站台
while (B < n)
{
if (A == a[B]) //列车A直接开走,不进站
{
A++;
B++;
}
else if (!s.empty() && a[B] == s.top()) //栈不空,并且栈顶元素与目标序列相等,a[B]出站
{
s.pop();
B++;
}
else if (A <= n) //A进站
{
s.push(A); A++;
}
else
{
flag = 1;
break;
}
}
if (flag == 0)
return true;
else return false;
}
#include
using namespace std;
int main()
{
int n;
long long t[21];
t[0] = 1;
for (int i = 1; i <= 20; i++)
{
t[i] = t[i - 1] * (4 * i - 2) / (i + 1);
}
while (cin >> n)
{
cout << t[n] << endl;
}
return 0;
}