加载中...

ACM专题---做题目

简介

ACM
纯写题,写思路,写代码

题目

A+B问题I

思路: 不管是a还是b,反正是两变量,而且你的输入不能断,输入一对a、b,给出和的结果;那就是定义两变量,用一个循环,搞定

example

#include <iostream>

using namespace std;
int main()
{
	int a, b;
	while (cin >> a >> b)
		cout << a + b << endl;
	return 0;
}

A+B问题II


思路:与上方问题保持一致,但它给多了一个N,其实就是一个输入N的循环

example

#include <iostream>
int main()
{
	int N;
	int a, b;
	while (std::cin >> N)
	{
		while (N--)
		{
			std::cin >> a >> b;
			std::cout << a + b << std::endl;
		}
	}
	return 0;
}

A+B问题III

思路:与上面的大循环一样的结构,增加了标志输入结束,其实就是一个判断条件,不需要计算,那中断这个循环就不会计算了

example

#include <iostream>
int main()
{
    int a, b;
	while (std::cin >> a >> b)
	{
		if (0 == a && 0 == b)
			break;
		std::cout << a + b << std::endl;
	}
	return 0;
}

A+B问题IV

思路:与上面的大循环一样的结构,但是循环的条件变了,变成输入N

example

#include <iostream>
int main()
{
	int N;
	int a, sum = 0;
	while (std::cin >> N)
	{
		if (0 == N)
			break;
		while (N--)
		{
			std::cin >> a;
			sum += a;
		}
		std::cout << sum << std::endl;
		sum = 0;
	}
	return 0;
}

A+B问题VII

思路:很简单,就是在I的基础上加多一个换行符

example

#include <iostream>
int main()
{
	int a, b;
	while (std::cin >> a >> b)
	{
		std::cout << a + b << std::endl;
		std::cout << std::endl;
	}
	return 0;
}

A+B问题VIII

思路:两层循环一个是总的输出M,然后是单个输出的数量N

example

#include <iostream>
int main()
{
	int M, N;
	int a, sum = 0;
	while (std::cin >> M)
	{
		while (M--)
		{
			std::cin >> N;
			while (N--)
			{
				std::cin >> a;
				sum += a;
			}
			std::cout << sum << std::endl;
			sum = 0;
			if (0 != M)
				std::cout << std::endl;
		}
	}
	return 0;
}

平均绩点

思路:假设输入是一个字符串,我们只需要提取字符串里的字母就够了,然后记录有几个字母,记一下字母所代表数字的总和

example

#include <iostream>
#include <string>
#include<sstream>
#include <stdio.h>
int main() {
	int num = 0;//记录有几个字母
	double sum = 0.0;//总和
	std::string str;//输入
	bool flag = false;//判断是否输出Unknown
	while (getline(std::cin, str)) {  //getline函数的使用
		for (int i = 0; i < str.size(); i++) {
			switch (str[i]) {  //字符串[]重载
			case 'A':
			{
				num++;
				sum += 4;
				break;
			}
			case 'B':
			{
				num++;
				sum += 3;
				break;
			}
			case 'C':
			{
				num++;
				sum += 2;
				break;
			}
			case 'D':
			{
				num++;
				sum += 1;
				break;
			}
			case 'F':
			{
				num++;
				sum += 0;
				break;
			}
			case ' ':
				break;
			default:
				flag = true;
				break;
			}
		}
		if (flag) {
			std::cout << "Unknown" << std::endl;
			num = 0;
			sum = 0;
			flag = false;
		}
		else {
			printf("%0.2lf\n", sum / num);
			num = 0;
			sum = 0;
		}
	}
    return 0;
}

搭积木

思路:最少的移步,我们可以看到这题就是一个找规律的题目
1. 举例子,也就是递推法
2. 找到相似的公式一步一步逼近你要的结果---逼近法

example

//我用的是第一种方法
#include <iostream>
#include <vector>

int MoveLeastStep(int num)  //找到最少移动步数
{
	std::vector<int> height;  //容器用来接收输入的高
	int sum = 0;
	for (int i = 0; i < num; i++) {
		int a;
		std::cin >> a; // 输入
		height.push_back(a); //接收
		sum += height[i]; //求和
	}
	int average = sum / num; //求平均
	int leaststep = 0; 
	for (int i = 0; i < num; i++) {
		if (height[i] - average > 0) // height[i] - average 这个数如果循环走num次,
                //就会为了,其中正负数相抵消,所以你要记录全正的,或者全负的数,就是移动最少的次数
			leaststep += height[i] - average;
	}
	return leaststep;
}

void test1()
{
	int num;
	while (std::cin >> num)
	{
	    if (0 == num)
	        break;
		int least = MoveLeastStep(num);
		std::cout << least << std::endl;
		std::cout << std::endl;
	}

}



int main()
{
    
    test1();
    return 0;
}

奇怪的信

思路:

  1. 取各个位置上的数,判断是否为偶数
    2.求和

example

#include <iostream>

int main(){
    int num;
    while (std::cin >> num) {
        int n = num;
        int sum = 0;
        while (n) {
            if ((n % 10) % 2 == 0)
                sum += n % 10;
            n /= 10;
        }
        std::cout << sum << std::endl;
        std::cout << " ";
        sum = 0;
    }
    return 0;
}

运营商活动

思路:

  1. 最开始的钱数就是天数,我们要搞清钱数跟天数的关系
    2.后面送的钱,我们单独算

example

#include <iostream>



int main() {
    int M, K;
    int re = 0;
    int sum = 0;
    while (true) {
        std::cin >> M >> K;
        if (M == 0 && K == 0)
            break;
        //最开始的钱
        sum += M;
        int song_num = 0;
        //最开始的钱通过K的转化,又可以多song_num天
        //19 / 3 = 6···1
        //7 / 3 = 2···1
        //3 / 3 = 1···0
        //19+6+2+1 = 29
        while (M >= K) {
            song_num += M / K;
            re = M % K;
            M = M / K + re;
        }
        //std::cout << song_num << std::endl;
        sum += song_num;
        std::cout << sum << std::endl;
        sum = 0;
        re = 0;
    }
}

共同祖先

思路:用两个vector空间去存输入的数字,然后根据链式求和他们各有的数字,数字多的就是辈分小,数字少的就是备份大
eg:1356,246,这就是链式,然后第一个有4个数字,第二个有3个数字,所以输出为older

example

#include <iostream>
#include <vector>
int main() {
    int son, father;
    int sum_1 = 2, sum_2 = 2;
    int N;
    std::vector<int> v1, v2;
    int stand = 0;
    while (std::cin >> N) {
        int m = N;
        while(N--) {
            std::cin >> son >> father;
            v1.push_back(son);
            v2.push_back(father);
        }

        for(int i = 0; i < m; i++) {
            if (v1[i] == 1) {
                stand = i;
                break;
            }
        }
        for(int i = 0; i < m; i++) {
             if (v2[stand] == v1[i]) {
                 stand = i;
                 sum_1++;
             }
        }
        for(int i = 0; i < m; i++) {
            if (v1[i] == 2) {
                stand = i;
                break;
            }
        }
        for(int i = 0; i < m; i++) {
            if (v2[stand] == v1[i]) {
                stand = i;
                sum_2++;
            }
        }
        if (sum_1 == sum_2) std::cout << "You are my brother" << std::endl;
        else if (sum_1 > sum_2) std::cout << "You are my elder" << std::endl;
        else if (sum_1 < sum_2) std::cout << "You are my younger" << std::endl;
        // std::cout << "1:" << sum_1 << std::endl;
        // std::cout << "2:" << sum_2 << std::endl;
        sum_1 = 2;
        sum_2 = 2;
        v1.clear();
        v2.clear();
    }
    return 0;
}

打印数字图形

思路:我们把这个图形打印分成四部分,即四个象限,按示例的中心就是123454321,我们每次打印就分成了四小步,具体操作看代码吧

example

#include <iostream>

int main()
{
    int a;
    while(std::cin >> a) {
        for (int i = 0; i < a; i++) {//打印上n行

            //1. 打空格
            for (int ii = a - i - 1; ii > 0; ii--) {
                std::cout << " ";
            }

            //2. 打左边数字
            for (int iii = 1; iii <= (i + 1); iii++) {
                std::cout << iii;
            }
            
            //3. 打右边数字
            for (int iiii = i; iiii > 0; iiii--) {
                std::cout << iiii;
            }
            std::cout << std::endl;
        }
        for (int i = 0; i < a - 1; i++) { //打印下n行

            //1. 打空格
            for (int ii = 0; ii < (i + 1); ii++) {
                std::cout  << " ";
            }

            //2. 打左边数字
            for (int iii = 1; iii < a - i; iii++) {
                std::cout << iii;
            }

            //3. 打右边数字
            for (int iiii = a - i - 2; iiii > 0; iiii--) {
                std::cout << iiii;
            }
            std::cout << std::endl;
        }
    }
    
}

镂空三角形

思路:我们把这个图形打印分成四部分,(空格+字母)这个打印格式可以当成同一种,具体操作看代码吧

  1. 左边空格+字母
  2. 左边空格
  3. 右边空格+字母
  4. 最后一行

example

#include <iostream>

int main() {
    char ch;
    int a;
    while (std::cin >> ch >> a) {
        if ('@' == ch) break;
        for (int i = 0; i < a; i++) {//i = 0~6变化

            //1. 在左边打印空格,最后空格后打一个ch
            for (int ii = a - i - 1; ii > 0; ii--) {
                std::cout << " ";
                if (ii == 1) {
                    std::cout << ch;
                }
            }

            //2. 在左边打印剩下的空格
            if (i < a - 1) {
                for (int iii = 0; iii < i; iii++) {
                    std::cout << " ";
                }

                //3. 在右边打印空格,最后一个空格打一个ch
                for (int iiii = 0; iiii < i - 1; iiii++) {
                    std::cout << " ";
                    if (iiii == i - 2) {
                        std::cout << ch;
                    }
                }

                if (i == 1) { // 特殊情况
                    std::cout << ch;
                }
            }

            //4. 最后一行全打印ch
            if (i == a - 1) {
                for (int i = 0; i < 2*a - 1; i++) {
                    std::cout << ch;
                }
            }
            std::cout << std::endl;
        }
        std::cout << std::endl;
    }
    return 0;
}

句子缩写

思路:这题我们可以看出来,靠这题已经不是思路的问题了,是考你的基本功扎不扎实

  1. 输入怎么接收?
  2. 处理过程就是空格+字母然后记录
  3. 完成字母的转化

注意:

  1. c++字符串,结尾不一定是'\0',所以判断结束条件-> index < str.length();
  2. str.at()访问string类比[]访问string类的好处是,at方法会检查越界;
  3. str.clear()只会清除str[0]元素的内容,并不会减小str的容量,而且后面的str[1]、str[2]不会做清除操作;

example

#include <iostream>
#include <string>
#include <limits>
#include <stdio.h>
int main() {
    //1
    //ad dfa       fga
    //在1后面有一个'\n'我们需要先清除
    //读取数据
    // int number;
    // std::string line;
    // // Read an integer
    // std::cin >> number;

    // // Remove the newline character from the input buffer
    // std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

    // // Read a line of text
    // std::getline(std::cin, line);
    // std::cout << line;
    
    //读取数据
    /*
    int n;
    std::cin >> n;
    std::string receiveStr;
    char ch;
    while((ch = getchar()) != '\n') ;
    getline(std::cin, receiveStr);
    std::cout << receiveStr;
    */
    
    int n;
    std::cin >> n;
    char ch;
    while((ch = getchar()) != '\n');//清除最后一个'\n'
    std::string saveStr = "";//最后的结果
    std::string receiveStr;//接收字符
    while(n--) {
 
        getline(std::cin, receiveStr);
        int pointer = 0;
        int receiveStrLen = receiveStr.length();
        //std::cout << "receiveStrLen" << receiveStrLen << std::endl;
        while (pointer < receiveStrLen) { 
            while (pointer < receiveStrLen && receiveStr.at(pointer) == ' ') pointer++;
            saveStr += receiveStr.at(pointer);
            pointer++;
            while (pointer < receiveStrLen && receiveStr.at(pointer) != ' ') pointer++;
            //std::cout << "pointer" << pointer << std::endl;
        }
        //std::cout << "pointer" << pointer << std::endl;
        int saveStrLen = saveStr.length();
        int correctPtr = 0;
        while (correctPtr < saveStrLen) {
            if (saveStr.at(correctPtr) >= 'a') {
                saveStr.at(correctPtr) -= 32;
            }
            correctPtr++;
        }
        std::cout << saveStr << std::endl;
        saveStr.clear();
        receiveStr.clear();
    }

    return 0;
}

posted @ 2023-11-01 15:24  一名博客  阅读(36)  评论(0编辑  收藏  举报