maxv

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后依次输出
代码如下:
cpp #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 就是丑数 暴力部分代码 如下
cpp 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个整数,分别是1,2,3,。。。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;
}

分类:

技术点:

相关文章: