The Summer Training Summary(STL) -- the first

The Summer Training Summary-- the first

A - vector的使用 UVa 101

关于vector 的几个注意点

  1. vector p
p.push_back();   送入数据
p.insert() 指定位置指定元素,指定位置n个相同元素,指定位置 区间元素
p.assign(); 赋值
p.pop_back(); 移除最后一个数据
p.erase(); 删除指定位置 或者 指定区间数据
p.resize();改变容器大小相当于保留N个元素
p.clear();   清空数据
p.empty(); 是否为空 p.size();元素数量p.front();返回第一个
p.begin(); p.end() 返回首末迭代器 

2.迭代器的创建 vector<int>::iterator it=p.begin(); (it++ 位置 与*it 内容)

  1. vector p[100] 可以直接当做 二维数组使用而且可以直接取出 任意行/列的数据 p[i][j];并且可以直接使用sort()进行行排序sort(p[i].begin(),p[i].end()); // sort(p[i].begin,p[i].begin()+n);当然 也允许 cmp的加入

问题分析

包含以下几个操作 move /pile(onto/over )
可以知道 可以将其中的 还原操作 以及移动 单独携程一个子函数
开一个 vector p[30]用于记录每个位置上的积木
move onto 与 over 区别在于 a的还原与否 if(判断onto)
pile 同上 不过包含了一个 捆绑操作 用insert() 与 erase()或者resize()进行擦除
对于 而这些都必须依赖于 一个查找函数 find() 用于 查找与记录 a/b的位置 以及操作的区间长度
代码如下

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
int n,a,b;
int disa,disb,ha,hb; 
vector<int> p[30];
void find(int num,int &h,int &dis)
{
	for(dis=0;dis<n;dis++)
	{
	     for(h=0;h<p[dis].size();h++)
		 {
		 	if(p[dis][h]==num)
		 	return ;   
		 }	
	}
	return ;
}
void cl(int h,int dis)
{
	for(int i=h+1;i<p[dis].size();i++)
	p[p[dis][i]].push_back(p[dis][i]);
	p[dis].resize(h+1);
	return ;
}
void pile(int dis,int h,int dis2)
{
     p[dis2].insert(p[dis2].end(),p[dis].begin()+h,p[dis].end());
     p[dis].resize(h);
     return ;
}
int main()
{
	cin>>n;
	for(int i=0;i<n;i++)
	p[i].push_back(i);
	string s;
	while(cin>>s&&s[0]!='q')
	{
		string ss;
		cin>>a>>ss>>b;
		
		find(a,ha,disa);
		find(b,hb,disb);
		
	if(disa==disb)
	continue;
		if(s[0]=='m')
		{
			cl(ha,disa);
			if(!ss.compare("onto"))
			{
				cl(hb,disb);
			}
			pile(disa,ha,disb);
		}
		else
		{
			if(!ss.compare("onto"))
			{
				cl(hb,disb);
			}
			pile(disa,ha,disb);
		}
	
}
			for(int i=0;i<n;i++)
			{
				cout<<i<<":";
               for(int j=0;j<p[i].size();j++)
			   {
			   	cout<<" "<<p[i][j];
			   }
			   cout<<endl;				
			}
return 0;
}

B - set的使用 【UVA - 10815】

set<>几个注意点

1.set mp 大部分操作 同 vector<>一样不多 他的数据投入是依赖于insert()也有一个
2.mp.count(int)用于记录某个数字出现与否因为 set是集合 只有 0/1的情况 集合内元素唯一

问题分析:

首先可以直接string整体读入 然后依次扫描 判断是否是为英文字符并 变成小写天计入一个新的string
中直至 读取到乱七八糟的而且 新的string不为空 丢入 set中最后清空 可能存在最后一组 判断丢入 建立迭代器 依次输出 nice…
代码如下:

#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
using namespace std;
 
int main(void) 
{
    string word;
    set<string> dict;
 
    while (cin >> word) {
        string cur = "";
        for (int i = 0; i < word.length(); i++) {
            if (isalpha(word[i]))//判断是否为 英文字母不分大小写
                cur += tolower(word[i]); //单个变为小写字母 函数 呢个strlwr()仅在VC里好使
                //不是标准的C语言库中的函数 还是忘记的好...
            else if (cur != "") {
                dict.insert(cur);
                cur = "";
            }
        }
        if (cur != "") 
            dict.insert(cur);
    }
 
    for (set<string>::iterator it = dict.begin(); it != dict.end(); it++)
        cout << *it << endl;
 
    return 0;
}
 

C - map的使用 UVa 156

map<,> 几个注意点

1.用法很广 感觉就是将 string,int int,int string,string建立一个映射关系
2.之前一直纠结 如何判断没有映射关系的时候建立 映射关系后来才知道给还有
3.map<int,int> mp mp.count(int) 就可以查询 是否有映射关系 返回的建立的映射数量

问题分析:

要求 输出没有 他所述的映射 将其输出 (先将每一位置单词化为 全小写 字典序)(目的 检测是否存在题目要求的映射)利用map建立<string,int>映射 第一次出现的
单词–所在位置 同时 第一次出现 统计数组++; 扫一遍统计数组 如果为1 就加入新的string数组中进行一遍sort后依次输出
代码如下:

#include<iostream>
#include<map>
#include<algorithm>
#include<cstring>
using namespace std;
string s[10000],ms[1000];
int sum[10000];
map <string,int > mp;
string  st (string a)
{
for(int i=0;i<a.length();i++)
{
   if(a[i]>=65&&a[i]<=90)
    a[i]+=32;
}
sort(a.begin(),a.end());
return a;
}
int main()
{
   int ans=0;
  while(cin>>s[ans++])
  {
  if(!s[ans-1].compare("#"))
  	break;
  string ss=st(s[ans-1]);
  if(!mp.count(ss))
  {
  mp[ss]=ans-1;
  sum[ans-1]=1;	
  }
  else
  {
  	sum[mp[ss]]++;
  } 
  }
  int cnt=0;
  for(int i=0;i<ans-1;i++)
   {
   	if(sum[i]==1)
       ms[cnt++]=s[i];
   }
   sort(ms,ms+cnt);
   for(int i=0;i<cnt;i++)
   cout<<ms[i]<<endl;
} 

D - queue的使用 (UVa 540)

queue<>的几个注意点

1.queue q; 先进先出
2.q.push(); 送入元素
q.front();返回队首元素.
3.q.pop();弹出队首元素
4.q.empty(); 判断队列是都为空 空为1非则0
5.q.size(); 返回 队列元素数量
…emmm 大概就是酱紫吧;

问题分析

模拟 开一个记录 队伍号 另一个 记录每一支队伍里的人
首先 对 每一队的队员进行映射 到所在队伍号
然后 对于每一名入队队员进行判断 所在队伍是都已经有人入队 就是.size()!=0
有就插进去 没有就所在队伍 入队 依次
出队的时候 依次从 队伍号的队列 取出首元素 每次出队判断 队伍号内是都还有人没有就 队伍号收元素出队 (具体还是看代码吧)

#include<iostream>
#include<queue>
#include<map>
#include<cstring>
using namespace std;
int main()
{
	string s;

int n,m,a,ans=0;;
while(cin>>n&&n)
	{
map<int ,int > team;
queue<int> qq,q[1000];
		ans++;
	for(int i=0;i<n;i++)
	{
	  cin>>m;
	  for(int j=0;j<m;j++)
	  {
	  	cin>>a;
	  team[a]=i;
	  }
	  }
	  cout<<"Scenario #"<<ans<<endl; 
	  while(cin>>s&&s[0]!='S')
	{
if (s[0]=='D')
		{
		int x=qq.front();
	    cout<<q[x].front()<<endl;
	    q[x].pop();
	    if(q[x].empty())
	    qq.pop();
		}
	else 
	{
		cin>>a;
		if(q[team[a]].empty())
			qq.push(team[a]);
		q[team[a]].push(a);
	}
	}
	cout<<endl;
	} 
	return 0;
 } 

E - 优先队列的使用 Uva 136

优先队列的几个注意点

之前写过一篇文章…(可以瞅一下)
优先队列浅析

问题分析: 他说 只能被 且不能被其他整除 由素数定义可知 就是只能被整除的意思…

这个题只要 输出答案就行…结果卡输出(必须要有 换行 \n)
思路1: 暴力 直接 从1开始 依次往后 根据丑数定义取余2 3 5为零就是无限除 只要最终答案为1 就是丑数 暴力部分代码 如下

long long ans=0,i,k;
for( k=1;k<990000000;k++)
{
   i=k;
   if(ans==1500)
   break;
   while(i%2==0)
   {
   	i/=2;
   }
   while(i%5==0)
   i/=5;
   while(i%3==0)
   i/=3;
   if(i==1)
   {
   ans++;
   cout<<k<<endl;	
   }
}

思路2: 既然只能被也就是说他只能是 2 3 5 的倍数 从
1开始出队 依次乘以2 3 5 并加入 优先队列 并统计-----注意 同一个数只能出现一次
直至统计结果为 1500时候 输出 并 break;
代码如下:

#include<iostream>
#include<map>
#include<algorithm>
#include<cstring>
#include<queue>
#include<set>
using namespace std;
typedef long long ll;
int main()
{	
long long ans=0,i,k;
set<ll> s;
priority_queue<ll,vector<ll>,greater<ll > > qq;
qq.push(1);
s.insert(1);
int n[3]={2,3,5};
for(int i=1;;i++)
{
	ll x=qq.top();
	qq.pop();
	if(i==1500)
	{
	cout<<"The 1500'th ugly number is "<<x<<"."<<endl;
	break;
	}
	for(int j=0;j<3;j++)
	{
		ll xx=x*n[j];
		if(!s.count(xx))
		{
			s.insert(xx);
			qq.push(xx);
		}
	}	
}
return 0;
}

F - 全排列函数 (暂时不知道是哪个题)

记下一个固定模板就行 ,个人理解是它每次排序都直接作用于数组 所以输出的就是已经排完的序列

do{
	for(int I =0;i<n;i++)
       cout<<a[i]<<" ";
   cout<<endl;
}while(next_permutation(a,a+n));
给你N个整数,分别是123,。。。N。问你全排列的第M个排列为多少?
Input
输入包含几个测试用例。每个测试用例由两个数字组成,N和M(1<=N<=1000, 1<=M<=10000). 你可能会假设总有一个序列满足题目需求。输入在文件结束时终止。
Output
对于每个测试用例,您只需要输出满足题目要求的序列。输出序列时,应该在两个数字之间打印空格,但不要在最后一个数字之后输出任何空格。
Sample Input
6 4
11 8
Sample Output
1 2 3 5 6 4
1 2 3 4 5 6 7 9 8 11 10

代码如下:

#include<iostream>
#include<map>
#include<algorithm>
#include<cstring>
#include<queue>
#include<set>
using namespace std;
typedef long long ll;
int main()
{	
int n,m,a[1005],sum=0;
while(cin>>n>>m)
{
	sum=0;
	for(int i=0;i<n;i++)
	a[i]=i+1;
	do{
		sum++;
		if(sum==m)
		break;
	}while(next_permutation(a,a+n));
for(int i=0;i<n;i++)
{
	if(i<n-1)
	cout<<a[i]<<" ";
	else
	cout<<a[i]<<endl;
}
}
return 0;
}

第一周 训练(the second)
直转链接
↓ ↓ ↓ ↓
The Summer Training Summary(1)-- the second (点击转到)

发布了55 篇原创文章 · 获赞 1 · 访问量 991

猜你喜欢

转载自blog.csdn.net/weixin_43556527/article/details/102975871
今日推荐