String类的使用:
- string类只能用cout输出,不能用printf输出
- string类的函数
1) =, s.assign() // 赋以新值
2) swap() // 交换两个字符串的内容
3) +=, s.append(), s.push_back() // 在尾部添加字符
4) s.insert() // 插入字符
5) s.erase() // 删除字符
6) s.clear() // 删除全部字符
7) s.replace() // 替换字符
8) + // 串联字符串
9) ==,!=,<,<=,>,>=,compare() // 比较字符串
10) size(),length() // 返回字符数量
11) max_size() // 返回字符的可能最大个数
12) s.empty() // 判断字符串是否为空
13) s.capacity() // 返回重新分配之前的字符容量
14) reserve() // 保留一定量内存以容纳一定数量的字符
15) [ ], at() // 存取单一字符
16) >>,getline() // 从stream读取某值
17) << // 将谋值写入stream
18) copy() // 将某值赋值为一个C_string
19) c_str() // 返回一个指向正规C字符串(C_string)的指针 内容与本string串相同 有’\0’
20) data() // 将内容以字符数组形式返回 无’\0’
21) s.substr() // 返回某个子字符串
22) begin() end() // 提供类似STL的迭代器支持
23) rbegin() rend() // 逆向迭代器
24) get_allocator() // 返回配置器 - getline读入一行字符:getline(cin,string);
- string转换成char *:
string str = "Hello World"; int len = str.length(); char *data = new char[len+1]; strcpy(data, str.c_str());
string到char*的转换可以用string的一个成员函数strcpy实现
L1-006 连续因子
通过len控制连续因子的个数,可以通过N的范围确定最多只能到12的阶乘,取len从11~1进行模拟
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
int main()
{
int N;
scanf("%d",&N);
int n=sqrt(N);
int i,j;
long long int sum;
for(int len=11; len>=1; len--)
{
for(i=2; i<=n; i++)
{
sum=1;
for(j=i; j<=len-1+i; j++)
{
sum*=j;
if(sum>N) break;
}
if(N%sum==0)
{
printf("%d\n%d",len,i);
for(int k=i+1; k<j; k++)
printf("*%d",k);
printf("\n");
return 0;
}
}
}
printf("1\n%d\n",N);
return 0;
}
L2-001 紧急救援
最短路+数组维护路径数,救援队数量+路径还原
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 505;
const int INF = 0x3f3f3f3f;
int head[maxn],tot,num[maxn],cnt[maxn],vis[maxn],dis[maxn],a[maxn],pre[maxn];
struct Edge
{
int dest;
int next;
int weight;
} edge[maxn*maxn];
void add(int u,int v,int w)
{
edge[++tot].next=head[u];
edge[tot].weight=w;
edge[tot].dest=v;
head[u]=tot;
}
struct node
{
int pos,val;
friend bool operator < (node a,node b)
{
return a.val>b.val;
}
};
void Dijkstra(int s)
{
priority_queue<node> q;
for(int i=0; i<maxn; i++)
{
dis[i]=INF;
vis[i]=0;
}
q.push(node{s,0});
dis[s]=0;
num[s]=a[s];
while(!q.empty())
{
node u=q.top();
q.pop();
if(vis[u.pos])
continue;
vis[u.pos]=1;
for(int i=head[u.pos]; i!=0; i=edge[i].next)
{
int dest=edge[i].dest;
int weight=edge[i].weight;
if(dis[dest]>weight+u.val)
{
pre[dest]=u.pos;
dis[dest]=weight+u.val;
num[dest]=num[u.pos]+a[dest];
cnt[dest]=cnt[u.pos];
q.push(node{dest,dis[dest]});
}
else if(dis[dest]==weight+u.val)
{
cnt[dest]+=cnt[u.pos];
if(num[dest]<num[u.pos]+a[dest])
{
pre[dest]=u.pos;
num[dest]=num[u.pos]+a[dest];
q.push(node{dest,dis[dest]});
}
}
}
}
}
int main()
{
memset(pre,-1,sizeof(pre));
int n,m,s,d;
scanf("%d %d %d %d",&n,&m,&s,&d);
for(int i=0; i<n; i++)
scanf("%d",&a[i]),cnt[i]=1;
for(int i=0; i<m; i++)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
Dijkstra(s);
printf("%d %d\n",cnt[d],num[d]);
vector<int> path;
for(; d!=pre[s]; d=pre[d])
path.push_back(d);
reverse(path.begin(),path.end());
for(int i=0; i<path.size(); i++)
printf("%d%c",path[i],(i==path.size()-1)?'\n':' ');
}
L3-011 直捣黄龙
l2-001的加强版 需要用map来获取string对应的键值 然后三个数组维护三个值
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<iostream>
using namespace std;
const int maxn = 505;
const int INF = 0x3f3f3f3f;
int head[maxn],tot,num[maxn],cnt[maxn],vis[maxn],dis[maxn],a[maxn],pre[maxn];
int pn,cou[maxn];
string city[maxn],name;
map<string,int> mp;
struct Edge
{
int dest;
int next;
int weight;
} edge[maxn*maxn];
void add(int u,int v,int w)
{
edge[++tot].next=head[u];
edge[tot].weight=w;
edge[tot].dest=v;
head[u]=tot;
}
struct node
{
int pos,val;
friend bool operator < (node a,node b)
{
return a.val>b.val;
}
};
int getid(string s)
{
if(!mp.count(s))
{
mp[s]=pn++;
city[pn]=s;
}
return mp[s];
}
void Dijkstra(int s)
{
priority_queue<node> q;
for(int i=0; i<maxn; i++)
{
dis[i]=INF;
vis[i]=0;
}
q.push(node{s,0});
dis[s]=0;
num[s]=a[s];
while(!q.empty())
{
node u=q.top();
q.pop();
if(vis[u.pos])
continue;
vis[u.pos]=1;
for(int i=head[u.pos]; i!=0; i=edge[i].next)
{
int dest=edge[i].dest;
int weight=edge[i].weight;
if(dis[dest]>weight+u.val)
{
pre[dest]=u.pos;
dis[dest]=weight+u.val;
num[dest]=num[u.pos]+a[dest];
cnt[dest]=cnt[u.pos];
cou[dest]=cou[u.pos]+1;
q.push(node{dest,dis[dest]});
}
else if(dis[dest]==weight+u.val)
{
cnt[dest]+=cnt[u.pos];
if(cou[dest]<cou[u.pos]+1)
{
pre[dest]=u.pos;
num[dest]=num[u.pos]+a[dest];
cou[dest]=cou[u.pos]+1;
q.push(node{dest,dis[dest]});
}
else if(cou[dest]==cou[u.pos]+1)
{
if(num[dest]<num[u.pos]+a[dest])
{
pre[dest]=u.pos;
num[dest]=num[u.pos]+a[dest];
q.push(node{dest,dis[dest]});
}
}
}
}
}
}
int main()
{
memset(pre,-1,sizeof(pre));
int n,m,s,d;
scanf("%d %d",&n,&m);
cin>>name,s=getid(name);
cin>>name,d=getid(name);
int id;
for(int i=0; i<n-1; i++)
{
cnt[i]=cou[i]=1;
cin>>name,id=getid(name);
scanf("%d",&a[id]);
}
for(int i=0; i<m; i++)
{
int a,b,c;
cin>>name,a=getid(name);
cin>>name,b=getid(name);
scanf("%d",&c);
add(a,b,c);
add(b,a,c);
}
Dijkstra(s);
int t=d;
vector<int> path;
for(; d!=pre[s]; d=pre[d])
path.push_back(d);
reverse(path.begin(),path.end());
for(int i=0; i<path.size(); i++)
{
cout<<city[path[i]+1];
printf("%s",(i==path.size()-1)?"\n":"->");
}
printf("%d %d %d\n",cnt[t],dis[t],num[t]);
}
L2-004 这是二叉搜索树吗?
首先不管是镜像还是非镜像,第一个遍历的一定是根节点,然后根据二叉搜索树的性质可以找到左子树和右子树,然后递归寻找下去。
#include<vector>
#include<cstdio>
using namespace std;
const int maxn = 1020;
const int INF = 0x3f3f3f3f;
bool ismirror;
int pre[maxn];
vector<int> now;
void f(int l,int r)
{
if(l>r) return;
int rson=l+1;
int lson=r;
if(!ismirror)
{
while(lson>l&&pre[lson]>=pre[l]) lson--;
while(rson<=r&&pre[rson]<pre[l]) rson++;
}
else
{
while(lson>l&&pre[lson]<pre[l]) lson--;
while(rson<=r&&pre[rson]>=pre[l]) rson++;
}
if(rson-lson!=1) return;
f(l+1,lson);
f(rson,r);
now.push_back(pre[l]); //存每一个根节点
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&pre[i]);
f(0,n-1);
if(now.size()!=n)
{
ismirror=1;
now.clear();
f(0,n-1);
if(now.size()!=n) printf("NO");
else
{
printf("YES\n");
for(int i=0; i<now.size(); i++)
{
printf("%d%c",now[i],(i==(now.size()-1))?'\n':' ');
}
}
}
else
{
printf("YES\n");
for(int i=0; i<now.size(); i++)
{
printf("%d%c",now[i],(i==(now.size()-1))?'\n':' ');
}
}
}
L2-006 树的遍历
每次通过后序遍历形成的数组找出根节点,注意每次递归都要放弃对根节点的遍历
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 35;
vector<int> tree[maxn];
int tail[maxn],mid[maxn],k,n;
int build(int L,int R,int l,int r)
{
if(L>R)
return 0;
int root=tail[r],i;
for(i=L; i<=R; i++)
{
if(mid[i]==root)
break;
}
int len=i-L;
tree[root].push_back(build(L,i-1,l,l+len-1));
tree[root].push_back(build(i+1,R,l+len,r-1));
return root;
}
void bfs(int root)
{
queue<int> q;
q.push(root);
while(!q.empty())
{
int a=q.front();
q.pop();
for(int i=0;i<tree[a].size();i++)
{
if(tree[a][i]==0) continue;
k++;
printf("%d",tree[a][i]);
if(k!=n-1) printf(" ");
else printf("\n");
q.push(tree[a][i]);
}
}
}
int main()
{
scanf("%d",&n);
for(int i=0; i<n; i++)
scanf("%d",&tail[i]);
for(int i=0; i<n; i++)
scanf("%d",&mid[i]);
int root=build(0,n-1,0,n-1);
if(n>1) printf("%d ",root);
else printf("%d",root);
bfs(root);
}