zoukankan      html  css  js  c++  java
  • The Summer Training Summary(1)-- 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

    优先队列的几个注意点

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

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

    这个题只要 输出答案就行....结果卡输出(必须要有 换行 )
    思路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个整数,分别是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;
    }
    

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

  • 相关阅读:
    VB.Net常用数学函数整理
    VB6转换C#2010步骤及工具
    通用MD5加密演示
    一行代码解决VB.NET中Dialog窗体销毁不刷新主窗体
    JavaScript中defer 和onload的执行顺序
    XML读取事例程序
    C#正则表达式使用指引
    使用Response.ContentType 来控制下载文件的类型
    重载、重写的简易解释
    西历转和历函数
  • 原文地址:https://www.cnblogs.com/maxv/p/11218920.html
Copyright © 2011-2022 走看看