编程案例C++

学习编程题C++(一)
1.我叫王大锤,是一家出版社的编辑。我负责校对投稿来的英文稿件,这份工作非常烦人,因为每天都要去修正无数的拼写错误。但是,优秀的人总能在平凡的工作中发现真理。我发现一个发现拼写错误的捷径:

  1. 三个同样的字母连在一起,一定是拼写错误,去掉一个的就好啦:比如 helllo -> hello
  2. 两对一样的字母(AABB型)连在一起,一定是拼写错误,去掉第二对的一个字母就好啦:比如 helloo -> hello
  3. 上面的规则优先“从左到右”匹配,即如果是AABBCC,虽然AABB和BBCC都是错误拼写,应该优先考虑修复AABB,结果为AABCC

我特喵是个天才!我在蓝翔学过挖掘机和程序设计,按照这个原理写了一个自动校对器,工作效率从此起飞。用不了多久,我就会出任CEO,当上董事长,迎娶白富美,走上人生巅峰,想想都有点小激动呢!
……
万万没想到,我被开除了,临走时老板对我说: “做人做事要兢兢业业、勤勤恳恳、本本分分,人要是行,干一行行一行。一行行行行行;要是不行,干一行不行一行,一行不行行行不行。” 我现在整个人红红火火恍恍惚惚的……

请听题:请实现大锤的自动校对程序

#include <iostream>
#include <string>
 
using namespace std;
 
const int N = 1000010;
 
int main()
{
	int n;
	cin >> n;
	char str[N];
	while (n--) {
		cin >> str;
		int j = 0;
		for (int i = 0; str[i]; i++) {
			str[j++] = str[i];
			if (j >= 3 && str[j - 3] == str[j - 2] && str[j - 2] == str[j - 1])
				j--;
			if (j >= 4 && str[j - 4] == str[j - 3] && str[j - 2] == str[j - 1])
				j--;
		}
		str[j] = '\0';
		cout << str << endl;
	}
}

2.我叫王大锤,是一名特工。我刚刚接到任务:在字节跳动大街进行埋伏,抓捕恐怖分子孔连顺。和我一起行动的还有另外两名特工,我提议

  1. 我们在字节跳动大街的N个建筑中选定3个埋伏地点。
  2. 为了相互照应,我们决定相距最远的两名特工间的距离不超过D。

我特喵是个天才! 经过精密的计算,我们从X种可行的埋伏方案中选择了一种。这个方案万无一失,颤抖吧,孔连顺!
……
万万没想到,计划还是失败了,孔连顺化妆成小龙女,混在cosplay的队伍中逃出了字节跳动大街。只怪他的伪装太成功了,就是杨过本人来了也发现不了的!

请听题:给定N(可选作为埋伏点的建筑物数)、D(相距最远的两名特工间的距离的最大值)以及可选建筑的坐标,计算在这次行动中,大锤的小队有多少种埋伏选择。
注意:

  1. 两个特工不能埋伏在同一地点
  2. 三个特工是等价的:即同样的位置组合(A, B, C) 只算一种埋伏方法,不能因“特工之间互换位置”而重复使用
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;

//求排列组合
long long C(long long n)
{
    if (n < 0)
        return 0;
    else
        return (n-1)*n/2;
}   

int main()
{
    long long n,d,i,j,count = 0;
    cin >> n >> d;
    long long *arr = (long long*)calloc(sizeof(long long), n);
    
    cin >> arr[0] >> arr[1];
    for (i = 2, j = 0; i < n; i++)
    {
        cin >> arr[i];
        while (arr[i] - arr[j] > d)
            j++;
        count += C(i-j);
    }
    cout << count % 99997867;
    free(arr);
    
    return 0;
}

3.小包最近迷上了一款叫做雀魂的麻将游戏,但是这个游戏规则太复杂,小包玩了几个月了还是输多赢少。
于是生气的小包根据游戏简化了一下规则发明了一种新的麻将,只留下一种花色,并且去除了一些特殊和牌方式(例如七对子等),具体的规则如下:

总共有36张牌,每张牌是1~9。每个数字4张牌。
你手里有其中的14张牌,如果这14张牌满足如下条件,即算作和牌
14张牌中有2张相同数字的牌,称为雀头。
除去上述2张牌,剩下12张牌可以组成4个顺子或刻子。顺子的意思是递增的连续3个数字牌(例如234,567等),刻子的意思是相同数字的3个数字牌(例如111,777)

例如:
1 1 1 2 2 2 6 6 6 7 7 7 9 9 可以组成1,2,6,7的4个刻子和9的雀头,可以和牌
1 1 1 1 2 2 3 3 5 6 7 7 8 9 用1做雀头,组123,123,567,789的四个顺子,可以和牌
1 1 1 2 2 2 3 3 3 5 6 7 7 9 无论用1 2 3 7哪个做雀头,都无法组成和牌的条件。

现在,小包从36张牌中抽取了13张牌,他想知道在剩下的23张牌中,再取一张牌,取到哪几种数字牌可以和牌。

#include<iostream>
#include<map>
#include<vector>
using namespace std;

bool isHu(map<int, int> mp,int num)
{
    if(num <= 0)
        return true;
    while(mp[mp.begin()->first] == 0)
        mp.erase(mp.begin());
    map<int, int>::iterator it = mp.begin();
    if(num%3!=0 && (it->second) >= 2)
    {
        mp[it->first] -= 2;
        if(isHu(mp, num-2))
            return true;
        mp[it->first] += 2;
    }
    if((it->second) >= 3)
    {
        mp[it->first] -= 3;
        if(isHu(mp, num - 3))
            return true;
        mp[it->first] += 3;
    }
    if((it->second) > 0 && mp[(it->first)+1] > 0 && mp[(it->first)+2] > 0)
    {
        mp[it->first]--;
        mp[(it->first)+1]--;
        mp[(it->first)+2]--;
        if(isHu(mp, num-3))
            return true;
        mp[(it->first)]++;
        mp[(it->first) + 1]++;
        mp[(it->first) + 2]++;
    }
    return false;
}

int main(){
    map<int, int> mp;
    int tmp;
    for(int i = 0;i < 13;i++){
        cin >> tmp;
        mp[tmp]++;
    }
    vector<int> ans;
    for(int i = 1;i < 10;i++)
    {
        if(mp[i] < 4)
        {
            ++mp[i];
            if(isHu(mp, 14))
                ans.push_back(i);
            --mp[i];
        }
    }
    if(ans.empty())
        cout << 0 << endl;
    else{
        for(int i:ans)cout << i << ' ';
    }
    
    return 0;
}


4.小明是一名算法工程师,同时也是一名铲屎官。某天,他突发奇想,想从猫咪的视频里挖掘一些猫咪的运动信息。为了提取运动信息,他需要从视频的每一帧提取“猫咪特征”。一个猫咪特征是一个两维的vector<x, y>。如果x_1=x_2 and y_1=y_2,那么这俩是同一个特征。
因此,如果喵咪特征连续一致,可以认为喵咪在运动。也就是说,如果特征<a, b>在持续帧里出现,那么它将构成特征运动。比如,特征<a, b>在第2/3/4/7/8帧出现,那么该特征将形成两个特征运动2-3-4 和7-8。
现在,给定每一帧的特征,特征的数量可能不一样。小明期望能找到最长的特征运动。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<bits/stdc++.h>
using namespace std;

map< pair<int,int>, set<int> > m1;
int main()
{
  //  freopen("in","r",stdin);
    int n,m;
    cin >> n;
    while(n--)
    {
        cin >> m;
        int maxn = 0,now = 0;
        int k;
        int x,y;
        for(int i = 0;i < m;i++)
        {
            cin >> k;
            for(int j = 0;j < k;j++)
            {
                cin >> x >> y;
                m1[make_pair(x,y)].insert(i);
            }
        }
        for(map <pair<int,int>, set<int> >::iterator it=m1.begin();it!=m1.end();it++)
        {
            int num = 0;
            int sum = 1;
            set<int>::iterator itt=it->second.begin();
            num = *itt;
            itt++;
            for(;itt!=it->second.end();itt++)
            {
                if(*itt==num+1)
                {
                    sum++;
                    num = *itt;
                }
                else 
                    {
                    	num = *itt;
                    	maxn = max(maxn,sum);
                    	sum = 1;
                	}
            	}
            	if(itt==it->second.end()) maxn = max(maxn,sum);
        	}
        	cout << max(maxn,now) << endl;
    }
 return 0;
}

5.小明目前在做一份毕业旅行的规划。打算从北京出发,分别去若干个城市,然后再回到北京,每个城市之间均乘坐高铁,且每个城市只去一次。由于经费有限,希望能够通过合理的路线安排尽可能的省一些路上的花销。给定一组城市和每对城市之间的火车票的价钱,找到每个城市只访问一次并返回起点的最小车费花销。

#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;

int getAns(vector<vector<int>> &nums){

    int M = 0x7ffffff;
    int n = nums.size();
    vector<vector<int>> dp(1<<n, vector<int>(n,M));
    dp[1][0] = 0;
    for(int i=1; i<n; i++) dp[1<<i][i] = M;
    for(int i=1; i<(1<<n); i++){
        for(int j=0; j<n; j++){
            if(dp[i][j]!=M){
                for(int k=0; k<n; k++){
                    if((i&(1<<k))==0){
                        dp[i|(1<<k)][k] = min(dp[i|(1<<k)][k], dp[i][j]+nums[j][k]);
                    }
                }
            }
        }
    }
    int ans = M;
    for(int i=1; i<n; i++){
        ans = min(ans, dp[(1<<n)-1][i]+nums[i][0]);
    }
    return ans;
}
int main(){
    int n;
    while(cin>>n){
        vector<vector<int>> edges(n,vector<int>(n,0));
        int x;
        for(int i=0; i<n; i++){
            for(int j=0; j<n; j++){
                cin>>edges[i][j];
            }
        }
        cout<<getAns(edges)<<endl;
    }
    return 0;
}

6.Z国的货币系统包含面值1元、4元、16元、64元共计4种硬币,以及面值1024元的纸币。现在小Y使用1024元的纸币购买了一件价值为N(0<N<1024)的商品,请问最少他会收到多少硬币?

#include<iostream>
#include<string>
using namespace std;
int main(){
	int n;
	cin>>n;
	int cnum1,cnum2,cnum3,cnum4;
	cnum1=(1024-n)/64;                          //64元硬币的数量 
	cnum2=((1024-n)%64)/16;                     //16元硬币的数量 
	cnum3=(((1024-n)%64)%16)/4;                 //4元硬币的数量 
	cnum4=(1024-n)-(cnum1*64+cnum2*16+cnum3*4); //1元硬币的数量
	cout<<cnum1+cnum2+cnum3+cnum4<<endl;
	return 0;
}

7.机器人正在玩一个古老的基于DOS的游戏。游戏中有N+1座建筑——从0到N编号,从左到右排列。编号为0的建筑高度为0个单位,编号为i的建筑的高度为H(i)个单位。

起初, 机器人在编号为0的建筑处。每一步,它跳到下一个(右边)建筑。假设机器人在第k个建筑,且它现在的能量值是E, 下一步它将跳到第个k+1建筑。它将会得到或者失去正比于与H(k+1)与E之差的能量。如果 H(k+1) > E 那么机器人就失去 H(k+1) - E 的能量值,否则它将得到 E - H(k+1) 的能量值。

游戏目标是到达第个N建筑,在这个过程中,能量值不能为负数个单位。现在的问题是机器人以多少能量值开始游戏,才可以保证成功完成游戏?

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

int main()
{
    int N;
    int ans = 0;
    cin >> N;
    vector<int>D(N,0);
    for(int i = 0;i < N;i++)
        cin >> D[i];
    for(int j = N-1;j >= 0;j--)
    {
        ans = ceil((D[j]+ans)/2.0);//注意c++中除法整数/整数为0,ceil向上取整要整数/float类型
    }
    cout << ans << endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值