模拟 枚举 贪心(C++ 题目 代码 注解)

目录

题目一:

题目描述

输入描述:

输出描述:

输入

输出

说明

代码:

题目二:

题目描述

输入描述:

输出描述:

输入

输出

代码: 

题目三:

题目描述

输入描述:

输出描述:

输入

输出

输入

输出

输入

输出

输入

输出

说明

输入

输出

代码: 

题目四:

题目描述

输入描述:

输出描述:

输入

输出

代码:

题目五:

题目描述

输入描述:

输出描述:

输入

输出

代码: 

 题目六:

题目描述

输入描述:

输出描述:

输入

输出

说明

代码: 

题目七:

题目描述

输入描述:

输出描述:

输入

输出

说明

代码:

题目一:

题目描述

小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章。

这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换。对于每个英文单词,软件会先在内存中查找这个单词的中文含义,如果内存中有,软件就会用它进行翻译;如果内存中没有,软件就会在外存中的词典内查找,查出单词的中文含义然后翻译,并将这个单词和译义放入内存,以备后续的查找和翻译。

假设内存中有 MMM 个单元,每单元能存放一个单词和译义。每当软件将一个新单词存入内存前,如果当前内存中已存入的单词数不超过 M−1M−1M−1,软件会将新单词存入一个未使用的内存单元;若内存中已存入MMM 个单词,软件会清空最早进入内存的那个单词,腾出单元来,存放新单词。

假设一篇英语文章的长度为 NNN 个单词。给定这篇待译文章,翻译软件需要去外存查找多少次词典?假设在翻译开始前,内存中没有任何单词。

输入描述:

输入共 2 行。每行中两个数之间用一个空格隔开。
第一行为两个正整数 MMM 和 NNN,代表内存容量和文章的长度。
第二行为 NNN 个非负整数,按照文章的顺序,每个数(大小不超过 1000)代表一个英文单词。文章中两个单词是同一个单词,当且仅当它们对应的非负整数相同。

输出描述:

共 1 行,包含一个整数,为软件需要查词典的次数。

示例1

输入

3 7

1 2 1 5 4 4 1

输出

5

说明

整个查字典过程如下:每行表示一个单词的翻译,冒号前为本次翻译后的内存状况:
空:内存初始状态为空。
1. 1:查找单词1 并调入内存。
2. 1 2:查找单词2 并调入内存。
3. 1 2:在内存中找到单词1。
4. 1 2 5:查找单词5 并调入内存。
5. 2 5 4:查找单词4 并调入内存替代单词1。
6. 2 5 4:在内存中找到单词4。
7. 5 4 1:查找单词1 并调入内存替代单词2。
共计查了5次词典。

代码:

#include<iostream>
#include<queue>
#include<map>
using namespace std;
int main()
{
    int m,n;
    cin>>m>>n;
    string s;
    queue<int>q;//存单词,即内存
    map<int,int>mp;//是否在内存里
    int ans=0;
    while(n--)
    {
        int x;
        cin>>x;
        if(mp[x]==0)//不在内存里
        {
            mp[x]=1;//赋为在内存里
            ans++;//数量加一
            if(q.size()==m)//内存里存的数等于m
            {
                mp[q.front()]=0;//第一个出队,赋为不在内存里
                q.pop();
            }
            q.push(x);
        }
    }
    cout<<ans;
}

题目二:

题目描述

栗主席(lizi)是某xxxx大学的一个不得了的程序猿,然而没想到吧,他竟然有女盆友,我们假设为QAQ!!!

那天,QAQ问栗子:你的小米5s的图像解锁密码到底是多少?

栗子:嘛?我仔细想想...

QAQ:你仿佛在逗我...

...

栗子:我的图像解锁用过好多次密码,后来都是用指纹解锁,所以忘记密码辣。但是我记得可能是那几个密码

QAQ:那你务必告诉我...

栗子: ...

然后,栗子就写下了一堆可能的密码,安卓图案解锁中,数字对应的位置已经标出。

但是栗子当然不想把真正的密码告诉QAQ,所以给QAQ的一系列的密码中,甚至有一些密码,是不符合安卓图案解锁的规则的。

QAQ也知道栗子肯定不老实,给了很多错的密码,甚至不符合规则的密码,所以想请你来找出,哪些密码是不符合规则的。

安卓图案解锁的密码有这样的一些特点:

1.每个数字最多只会被使用一次。

2.如果想直接连接两个数字,但是线段中会经过另一个数字,当且仅有那个数字已经在之前就被使用过了,才会合法。(比如你想从1直接连接到9,那么要么是1->5->9,要么是5在之前已经被使用过了,然后才能直接从1->9)

输入描述:

多组输入
每组输入占一行,包含一串数字(1~9),长度不超过30

输出描述:

输出这个安卓图案解锁是否合法,如果合法输出"YES",反之输出"NO" (请参照样例输出,不要输出引号)

示例1

输入

14569 1953 15963 15953

输出

YES
NO
YES
NO

代码: 

#include<iostream>
#include<map>
using namespace std;
int main()
{
    string s;
    while(cin>>s)
    {
        int a[10]={0,1,2,1,3,4,3,1,2,1};//标记相隔的为一种类型
        map<char,int>mp;//记录出现次数
        int flag=1;
        mp[s[0]]=1;
        for(int i=1;i<s.size();i++)
        {
            if(mp[s[i]]!=0)//出现过,则为0
            {
                flag=0;
                break;
            }
            mp[s[i]]++;//出现,加1
            int s1=s[i-1]-'0',s2=s[i]-'0';
            char c='0'+(s1+s2)/2;
            if(a[s1]==a[s2]&&mp[c]==0)//为相隔的,且中间的没出现,为0
            {
                flag=0;
                break;
            }
        }
        
        if(flag==1)
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;
    }
}

题目三:

题目描述

Froggy 分别给出 10 个数码的出现次数,你需要找到一个由这些数码组成的最小的数,满足:

1. 这个数是回文的。

2. 不能有前导 0。

注:假设这个数字长度是 LLL,那么这个数是回文的当且仅当对于任意的 i∈[1,L]i\in [1,L]i∈[1,L],第 iii 位的数码和第 L−i+1L-i+1L−i+1 位的数码相同。

快来帮帮 Froggy 吧!

输入描述:

一行 10 个自然数,分别表示数码 0∼90\sim 90∼9 的出现次数。

输出描述:

如果无解,只输出 “-1”。(不含引号)

否则,输出一个数表示最小的解。

示例1

输入

0 2 4 2 0 2 0 0 0 0

输出

1223553221

示例2

输入

1 1 4 5 1 4 0 0 0 0

输出

-1

示例3

输入

4 0 2 3 0 0 0 2 0 0

输出

20037373002

示例4

输入

2 0 0 0 0 0 0 0 0 1

输出

-1

说明

注意不能有前导 0。

示例5

输入

1 0 0 0 0 0 0 0 0 0

输出

0

代码: 

#include<iostream>
using namespace std;
int main()
{
    int shu[15];
    int sum=0,ji=0;
	for(int i=0;i<10;i++)
    {
		cin>>shu[i];//记数出现的次数
		sum+=shu[i];
		if(shu[i]%2!=0) 
            ji++;//奇数个出现的次数
	}
	if(ji>1||(shu[0]>1&&sum-shu[0]<2))
    {
       printf("-1\n");
	   return 0;
    }
    else
    {
       int a[110],k=0;
       for(int i=1;i<10;i++)//先做一遍,0不含的情况
       {
       	   if(shu[i]>=2)
           {
             a[k]=i;
			 a[sum-k-1]=i;
			 shu[i]-=2;
			 k++;
             break;
           }
	    }
	  for(int i=0;i<10;i++)//从0开始到9
      {
	      while(shu[i]>1)
          { a[k]=i;a[sum-k-1]=i;k++;shu[i]-=2; }
	      if(shu[i]==1) 
          {  a[(sum/2)]=i;}
	   }
	  for(int i=0;i<sum;i++)
      {
	  	cout<<a[i];
	   }   
	}
}

题目四:

题目描述

明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N ≤ 100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。

输入描述:

输入有2行,第1行为1个正整数,表示所生成的随机数的个数:N
第2行有N个用空格隔开的正整数,为所产生的随机数。

输出描述:

输出2行,第1行为1个正整数M,表示不相同的随机数的个数。
第2行为M个用空格隔开的正整数,为从小到大排好序的不相同的随机数。

示例1

输入

10
20 40 32 67 40 20 89 300 400 15

输出

8
15 20 32 40 67 89 300 400

代码:

#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
int main()
{
    int n,k=0,a[110];
    map<int,int> mp;//记录是否出现
    cin>>n;
    while(n--)
    {
        int x;
        cin>>x;
        if(mp[x]==0)//没出现,则加入数组
            a[k++]=x;
        mp[x]=1;
    }
    sort(a,a+k);//从小到大排序
    cout<<k<<endl;
    for(int i=0;i<k;i++)
        cout<<a[i]<<" ";
}

题目五:

题目描述

某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。

由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

输入描述:

第一行有两个整数:L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

输出描述:

包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。

示例1

输入

500 3
150 300
100 200
470 471

输出

298

代码: 

#include<iostream>
using namespace std;
int main()
{
    int l,m,a[11000]={0};
    cin>>l>>m;
    while(m--)//差分
    {
        int c,b;
        cin>>c>>b;
        a[c]+=1;
        a[b+1]-=1;
    }
    int sum=0;
    for(int i=1;i<=l;i++)//合并
    {
        a[i]+=a[i-1];
    }
    for(int i=0;i<=l;i++)
        if(a[i]==0)
            sum++;
    cout<<sum;
}

 题目六:

题目描述

为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯。一共有n张地毯,编号从1到n。现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上。地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的编号。注意:在矩形地毯边界和四个顶点上的点也算被地毯覆盖。

输入描述:

第一行,一个整数n,表示总共有n张地毯。
接下来的n行中,第i+1行表示编号i的地毯的信息,包含四个正整数a,b,g,k,每两个整数之间用一个空格隔开,分别表示铺设地毯的左下角的坐标(a,b)以及地毯在x轴和y轴方向的长度。
第n+2行包含两个正整数x和y,表示所求的地面的点的坐标(x,y)。

输出描述:

输出共1行,一个整数,表示所求的地毯的编号;若此处没有被地毯覆盖则输出-1。

示例1

输入

3
1 0 2 3
0 2 3 3
2 1 3 3
2 2

输出

3

说明

如下图,1号地毯用实线表示,2号地毯用虚线表示,3号用双实线表示,覆盖点(2,2)的最上面一张地毯是3号地毯。

代码: 

#include<iostream>
using namespace std;
const int N=103000;
int main()
{
    int n;
    cin>>n;
    int x[N],hx[N],y[N],hy[N];
    for(int i=1;i<=n;i++)
        cin>>x[i]>>y[i]>>hx[i]>>hy[i];
    int ans=0;
    int st,se;
    cin>>st>>se;
    for(int i=1;i<=n;i++)
    {
        if(st>=x[i]&&st<=x[i]+hx[i]&&se>=y[i]&&se<=y[i]+hy[i])//在该地毯的范围内
            ans=i;
    }
    cout<<ans;
}

题目七:

题目描述

www.02469.com(本网页纯属虚构,如有雷同,纯属巧合),是一个资源丰富的教学资源网站,好学的SK同学经常访问这个网站。通常来说,网站为了安全考虑,登录的时候都需要用户输入验证码,这就让SK同学非常不爽了。

SK同学希望你能帮他写一个程序来自动识别验证码的内容,验证码由小写字母和阿拉伯数字组成,你需要识别出其中所有的0,2,4,6,9以及这5个数字对应的英文单词,并按照它们在验证码中出现的顺序以数字形式输出。

为了表示感谢,SK同学愿意跟你分享他私藏的教学资源。

输入描述:

第一行是一个正整数T(≤ 10),表示测试数据的组数, 每组测试数据只有一行,包含一个长度不超过100000的只由小写字母和阿拉伯数字组成的非空字符串。

输出描述:

对于每组测试数据,输出一行字符串,表示识别出的验证码。

示例1

输入

2
onetwothreefourfiveseven
0two4six6siiiiix

输出

24
02466

说明

0 - zero
2 - two
4 - four
6 - six
9 - nine

代码:

#include <iostream>
#include <cstring>
using namespace std;
//s.substr(i,len)从s的i位置开始截取长度为len的串
int main() 
{
    int n;
    cin >> n;
    while (n--)
    {
        string s, num = "";
        cin >> s;
        for (int i = 0; i < s.size(); i++)
        {
            if (s[i] == '0' || s[i] == '2' || s[i] == '4' || s[i] == '6' || s[i] == '9')
            {
                num += s[i];
            }
            else if (s.substr(i, 4) == "zero")
            {
                num += '0';
            }
            else if (s.substr(i, 3) == "two")
            {
                num += '2';
            }
            else if (s.substr(i, 4) == "four")
            {
                num += '4';
            }
            else if (s.substr(i, 3) == "six")
            {
                num += '6';
            }
            else if (s.substr(i, 4) == "nine")
            {
                num += '9';
            }
        }
        cout << num << endl;
    }
    return 0;
}

  • 20
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值