实训-基础B

实训B

问题 A:统计字母个数

时间限制: 1 Sec 内存限制: 128 MB

题目描述

给定一段文章,请输出每个字母出现的次数。

输入

只有一组输入数据,该数据大小<10KB。 在文章中除最后一个字符外,只有小写字母、空格和换行符,没有另外的标点、数字和大写字母等。该文章以’#’结尾。

输出

输出格式为“C A”,C为’a’…’z’中的字母,A为出现次数,C和A之间空一格。

样例输入

here is the input
this is the article#

样例输出

a 1
b 0
c 1
d 0
e 5
f 0
g 0
h 4
i 5
j 0
k 0
l 1
m 0
n 1
o 0
p 1
q 0
r 2
s 3
t 5
u 1
v 0
w 0
x 0
y 0
z 0

代码

#include <iostream>//输入输出流库
using namespace std;  //命名空间std
int main() {  //主程序入口
     
    char ch;    
    int charArr[26]={0};  //用来存放每个字符的数量
     
    while(cin.get(ch)){   //逐个读取字符,遇到#则停止
        if(ch == '#'){
            break;
        }
        else{
            charArr[ch-'a']++;  //遇到对应的字符,计数+1
        }
    }
     
    for(int i=0; i<26 ; i++){  //循环数组,来输出不同字符的数量
        ch = 'a';
        ch += i;
        cout << ch << " " << charArr[i] << endl;
         
    }   
    return 0;  //程序结束
}

问题 B:小数化分数1

时间限制: 1 Sec 内存限制: 128 MB

题目描述

Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始化了起来,但小数很多,手工化起来很费劲,请你写一个程序把一个纯小数(0<=纯小数<1)化成最简分数。

输入

第一行是一个整数N,表示有多少组数据 每组数据只有一个小数,小数的位数不超过9位,不考虑循环小数。如遇0.0,则输出0/1。

输出

对每一个对应的小数化成最简分数后输出,占一行。

样例输入

3
0.5
0.128
0.36

样例输出

1/2
16/125
9/25

代码

#include <stdio.h>  //C语言标准库
#include <math.h>  //数学库
  
int gcd(int n,int m)  //求最大公因数
{
    int temp;
    while(m!=0)
    {
        temp = m;
        m=n%m;
        n=temp;
    }
    return n;
}
  
int main()  //主程序入口
{
    int n,i,j;
    scanf("%d",&n);  //获取测试数据组数
    for(i=0;i<n;i++)  //循环n次
    {
        char num[10]={0};  //声明一个字符数组用来存放小数
        int cnt = 0,snum = 0;
        scanf("%s",num);  //将小数字符数组来读取
        for(j=2;num[j];j++)  //计算小数点后的数字是多少
        {
            snum=snum*10+(num[j]-'0');  //将字符转化为数字计算分子
            cnt++; //计数小数点后数字的位数
        } 
        int cd = gcd(snum,pow(10,cnt));  //求最大公因数
        int bnum = pow(10,cnt);  //分母
        printf("%d/%d\n",snum/cd,bnum/cd);  //输出最简的分数形式
    }
    return 0;  //程序结束
}

问题 C:筛排处理

时间限制: 1 Sec 内存限制: 128 MB

题目描述

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

输入

每组输入数据的第一行含有一个正整数N,表示后面行中有N个随机整数。若N=0,表示处理结束,只需输出一个0即可。

输出

对应每组输入数据,输出一组数据,该数据由单独一行开头,内含一个N,表示后面有N个排好序的整数,其整数每十个一排,整数之间空一格。 每组输出数据之间空一行。

样例输入

12
2 4 6 17 20 40 43 45 60 64 85 98
17
35 75 40 61 56 21 85 61 50 83 52 22 44 68 51 80 38
0

样例输出

12
2 4 6 17 20 40 43 45 60 64
85 98

16
21 22 35 38 40 44 50 51 52 56
61 68 75 80 83 85

0

代码

#include <iostream>  //C++标准库
#include <algorithm>  //算法库
using namespace std;  //命名空间std
int main(){  //主程序入口
     
    int N, num,numArr[100];     //声明所需的变量和数组
    while(true){
        cin >> N;
        if(N==0){  //测试结束条件
            cout << 0 << endl;
            break;
        }
        for(int i=0;i<N;++i){  //将输入的数字放进数组里
            cin >> num; 
            numArr[i] = num;
        } 
        sort(numArr,numArr+N);  //利用sort函数,给数组排序
        int len = unique(numArr,numArr+N) - numArr ;  //计算去重后的数组长度
        cout << len << endl;  //输出排序好后的数组的长度
        for(int i=0;i<len;++i){  //输出排序好后的数组
            if(i!=0 &&i%10==0){
                cout << endl;
            }
             
            cout << numArr[i];
            if(i+1 < len){
                cout << " " ;
            }   
        }
        cout << endl;
        cout << endl;
     
    }
     return 0; //程序结束
     
}

问题 D: 产生冠军

时间限制: 1 Sec 内存限制: 128 MB

题目描述

有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛。球赛的规则如下:
如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能打败C。
如果A打败了B,B又打败了C,而且,C又打败了A,那么A、B、C三者都不可能成为冠军。
根据这个规则,无需循环较量,或许就能确定冠军。你的任务就是面对一群比赛选手,在经过了若干场撕杀之后,确定是否已经实际上产生了冠军。

输入

输入含有一些选手群,每群选手都以一个整数n(n<1000)开头,后跟n对选手的比赛结果。
比赛结果以一对选手名字(中间隔一空格)表示,前者战胜后者。
如果n为0,则表示输入结束。

输出

对于每个选手群,若你判断出产生了冠军,则在一行中输出“Yes”,否则在一行中输出“No”。

样例输入

3
Alice Bob
Smith John
Alice Smith
5
a c
c d
d e
b e
a d
0

样例输出

Yes
No

代码

#include <iostream>   //C++标准库
#include <cstdio>  //C头文件
#include <string>  //字符串类库
#include <algorithm>  //算法库
#include <stack> //栈库
#include <queue> //队列库
#include <set>   //集合库
  
using namespace std;  //命名空间std
  
int main()  //主程序入口
{
    int n;    //选手数量
    while(cin>>n) //通过输入流读取选手数量,并进行循环
    {
        if(n==0) //判断如果选手数量为 0,则退出循环。
        {
            break;
        }
        getchar();  //去除换行符影响
        string s1,s2;  //声明了两个字符串变量 s1 和 s2,用于保存选手的姓名
        set<string>st1,st2;  //声明了两个字符串集合 st1 和 st2,用于保存不同的选手姓名
        while(n--)  //根据选手数量进行循环,每次循环读取选手姓名,并将其插入到集合 st1 和 st2 中
        {
            cin>>s1>>s2;  //通过输入流读取选手的姓名
            st1.insert(s1);  //将选手姓名插入到集合中
            st1.insert(s2);
            st2.insert(s2);
        }
        if(st1.size()-st2.size()==1)   //判断集合 st1 的大小减去集合 st2 的大小是否等于 1,即是否有且仅有一个选手没有参加比赛
        {
            cout<<"Yes"<<endl;  //输出 "Yes",表示比赛结果合法
        }
        else
        {
            cout<<"No"<<endl;  //输出 "No",表示比赛结果不合法
        }
          
    }
    return 0;  //程序正常结束
}

问题E: 小数化分数2

时间限制: 1 Sec 内存限制: 128 MB

题目描述

Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢? 请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。

输入

第一行是一个整数N,表示有多少组数据。 每组数据只有一个纯小数,也就是整数部分为0。循环部分用()括起来。

输出

对每一个对应的小数化成最简分数后输出,占一行。

样例输入

3
0.(4)
0.5
0.32(692307)

样例输出

4/9
1/2
17/52

代码

#include <iostream>  //包含输入输出流库的头文件
#include <string>  //包含字符串处理库的头文件
#include <sstream>  /包含字符串流处理库的头文件
using namespace std;  //使用命名空间 std

int gcd(int, int);                  // 辗转相除法求最大公约数
void pure(int, int);                // 纯循环小数处理函数
void mix(int, int, int);            // 混循环小数处理函数
 
int main()//主函数入口
{
    int N, i, count, len, numer, denomin, j, num1, num2;//声明了一系列用于存储临时整数的变量
    int pos_point, pos_left, pos_right;//声明了用于存储位置的变量
    string str, s1, s2;//声明了字符串变量
    stringstream ss1, ss2;//声明了两个字符串流对象
    cin >> N;//输入一个整数 N
    for (i = 0; i < N; i++) {//开始一个循环,循环 N 次
        cin >> str;//输入一个字符串
        len = str.length();//获取字符串的长度
        pos_left = str.find('(');//查找字符串中 '(' 的位置
        pos_point = str.find('.');//查找字符串中 '.' 的位置
        denomin = 1;初始化分母为 1
        // 循环小数
        if (pos_left != string::npos) { //判断字符串中是否存在 '('
            pos_right = str.find(')');//查找字符串中 ')' 的位置
            count = pos_right - pos_left - 1;       // 计算循环节的长度
            // 循环节的数作分子
            s1 = str.substr(pos_left + 1, count);  //获取循环节的数作为分子。
            if (pos_left == pos_point + 1) {  //判断是否为纯循环小数的情况。
                ss1 << s1;//将字符串 s1 插入到字符串流 ss1 中。
                ss1 >> numer;         //将字符串流 ss1 中的内容转换为整数,存储在 numer 中。
                pure(numer, count);//调用函数 pure 处理纯循环小数
            }
            else {//若不为纯循环小数
                num1 = pos_left - pos_point - 1;//计算非循环节的小数部分的位数
                s2 = str.substr(pos_point + 1, num1);//获取非循环节的小数部分作为分母
                ss1 << s2 + s1;//将字符串 s2 和 s1 拼接后插入到字符串流 ss1 中
                ss1 >> numer;         // 将字符串流 ss1 中的内容转换为整数,存储在 numer 中
                ss2 << s2;//将字符串 s2 插入到字符串流 ss2 中
                ss2 >> num2;      // 将字符串流 ss2 中的内容转换为整数,存储在 num2 中
                // 分子用所有的小数部分减去非循环节的小数部分
                mix(numer - num2, num1, count);//调用函数 mix 处理混循环小数
                ss2.clear();//清空字符串流 ss2
            }
        }
        // 普通小数
        else {//处理普通小数的情况
            count = len - pos_point - 1;        // 小数点后长度
            // 小数点后有几位,分母中就有几个0
            for (j = 0; j < count; j++) {
                denomin *= 10;//分母中的每个 0
            }
            // 小数点后的数作分子
            s1 = str.substr(pos_point + 1, count);//获取小数点后的数作为分子
            ss1 << s1;//将字符串 s1 插入到字符串流 ss1 中
            ss1 >> numer;//将字符串流 ss1 中的内容转换为整数,存储在 numer 中
            cout << numer / gcd(numer, denomin) << '/' << denomin /gcd(numer, denomin) << endl;//输出最简分数形式
        }
        ss1.clear();//清空字符串流 ss1
    }
    return 0;//程序执行完毕,返回 0
}
 
int gcd(int n, int m) {//使用辗转相除法求最大公约数
    int temp;//声明一个临时变量
    temp = n % m;//计算 n 除以 m 的余数
    while (temp != 0) {//如果余数不等于 0,则继续循环
        n = m;//将 m 的值赋给 n
        m = temp;//将余数的值赋给 m
        temp = n % m;//再次计算 n 除以 m 的余数
    }
    return m;//返回最大公约数
}
 
void pure(int n, int c)//处理纯循环小数的情况
{
    int i = 0, temp = 0;/声明两个临时变量
    
    for (; i < c; i++) {//根据循环节的位数计算分母
        temp = temp * 10 + 9;//分母上添 9
    }
    cout << n / gcd(n, temp) << '/' << temp / gcd(n, temp) << endl;//输出最简分数形式
}
 
void mix(int n, int m, int c)//mix 函数的定义,处理混循环小数的情况。
{
    int i = 0, temp1 = 0, temp2 = 1, temp;//声明三个临时变量
    // 循环节有几位,就在分母上先添几个9
    for (; i < c; i++) {//根据循环节的位数计算分母
        temp1 = temp1 * 10 + 9;//在分母上添 9
    }
    // 小数部分不循环的小数有几位,就在9后面添几个0
    for (i = 0; i < m; i++) {//根据小数部分的位数计算分子
        temp2 *= 10;//在 9 后面添 0
    }
    temp = temp1 * temp2;//计算分母
    cout << n / gcd(n, temp) << '/' << temp / gcd(n, temp) << endl;//输出最简分数形式
}

问题 F: 恺撒密码

时间限制: 1 Sec 内存限制: 128 MB

题目描述

恺撒密码是一种简单的古典密码,其加密原理是:选取一个整数K(0<=K<=25),使得原文的每个字母向右移K位得到密文。假定k=2,那么’a’向右移动2位就是’c’;’b’移动2位就是’d’;’y’移动2位又回到了’a’;’z’移动2位成为了’b’.你的任务是编程,其功能是根据一个整数K,将原文加密。

输入

一共一组测试数据。该组测试数据第一行为整数K,第二行为一段只含有小写字母的原文。该组测试数据长度<=1000。

输出

输出一共一行,为加密后的数据。

样例输入

2 
abzy

样例输出

cdba

代码

#include <iostream>  //包含输入输出流库的头文件
#include <string> //包含字符串处理库的头文件
using namespace std; //使用命名空间 std
 
 
 
int main(){//主函数入口
    int n;//用于存储加密偏移量
    string str;//用于存储待加密的字符串
    cin >> n;//通过标准输入流 cin 获取加密偏移量 n 的值
    cin.ignore();//忽略之前输入的换行符,避免对后续字符串输入造成影响
    cin >> str;//通过标准输入流 cin 获取待加密的字符串
    for(int i=0; i < str.size() ;++i ){//遍历待加密字符串 str 中的每个字符
        str[i] ='a'+(str[i] - 'a'  + n)%26;//对每个字符进行凯撒密码加密处理
        cout << str[i];//输出加密后的字符
        
    }
   return 0;//程序结束
}

问题 G: 切割正方体

时间限制: 1 Sec 内存限制: 128 MB

题目描述

一些不同边长的长方体,需要切割成若干个相同的小正方体,因为材料宝贵,所以切割中不能浪费,而且以整数长度为切割单位。现在请你计算一下,一个长方体有几种切割方法。

输入

输入包含有一些组数据,每组数据含有长方体的长、宽、高(0<长、宽、高<2^63)三个数据,若三者皆为0,则计算结束。

输出

针对每个长方体,以独立一行输出一个切割方法数。

样例输入

15 45 75
3 3 3
0 0 0

样例输出

4
2

代码

#include <iostream>//C++标准库
#include <algorithm>//算法库
#include <vector> //向量库
using namespace std;//命名空间std
 
// 辗转相除法计算最大公约数
long long gcd(long long a, long long b) {
    while (b != 0) {
        long long temp = b;
        b = a % b;
        a = temp;
    }
    return a;  //返回最大公约数
}
 
 
// 找出一个数的所有因子
int find_factors(long long num) {
    int count =0;
    // 从 1 开始逐个检查到 num 的平方根
    for (long long i = 1; i * i <= num; ++i) {
        // 如果 i 是 num 的因子
        if (num % i == 0) {
            count++;
            // 如果 i 不是 num 的平方根,将 num/i 也添加到因子列表中
            if (i != num / i) {
                count++;
            }
        }
    }
 
    return count;
}
 
int main() {
    long long L, W, H;
    int count ;
    while (cin >> L >> W >> H) {
        // 若三者皆为0,则计算结束
        count =0;
        if (L == 0 && W == 0 && H == 0){
            break;
        }
 
        // 计算最大公约数
        long long common_divisor = gcd(gcd(L, W), H);
        count = find_factors(common_divisor);
 
        cout << count << endl;
    }
 
    return 0;  //程序结束
}

问题 H: 核反应堆

时间限制: 1 Sec 内存限制: 128 MB

题目描述

某核反应堆有两类事件发生:
高能质点碰击核子时,质点被吸收,放出3个高能质点和1个低能质点;
低能质点碰击核子时,质点被吸收,放出2个高能质点和1个低能质点。
假定开始的时候(0微秒)只有一个高能质点射入核反应堆,每一微秒引起一个事件发生,试确定n微秒时高能质点和低能质点的数目。

输入

输入含有一些整数n(0≤n≤33),以微秒为单位,若n为-1表示处理结束。

输出

分别输出n微秒时刻高能质点和低能质点的数量,高能质点与低能质点数量之间以逗号空格分隔。每个输出显示为一行。

样例输入

2 5
-1

样例输出

11, 4
571, 209

代码

#include <iostream>  //输入输出流库
using namespace std;  //命名空间std
 
// 模拟核反应堆中高能质点和低能质点数量的变化
void simulate_reactor(long long n) {
    long long high_energy_particles = 1; // 初始高能质点数量为1
    long long low_energy_particles = 0; // 初始低能质点数量为0
    long long new_low_energy,new_high_energy;
    for (int i = 0; i < n; ++i) {
        // 根据规则更新高能质点和低能质点数量
        new_high_energy = 3*high_energy_particles + 2*low_energy_particles;
        new_low_energy =  high_energy_particles + low_energy_particles;
        
 
        // 更新质点数量
        high_energy_particles = new_high_energy;
        low_energy_particles = new_low_energy;
 
 
 
        // 输出当前时刻的质点数量
    }
    cout << high_energy_particles << ", " << low_energy_particles << endl;
}
 
int main() {  //程序入口
    long long n;  
     
    cin >> n;
 
    while (n != -1) {
        simulate_reactor(n);
        cin >> n;
    }
 
    return 0;
}

问题 I: 天花板

时间限制: 1 Sec 内存限制: 128 MB

题目描述

给定一个实数A,请输出一个整数B使得B>=A,并且不存在另外一个整数b,满足b>=A且B>b。

输入

第一行为整数N表示一共有N个实数A。接下来每行一个实数Ai。Ai的小数位数不超过8位。

输出

输出一共N行,每行对应的整数Bi。

样例输入

4
5.99999999
5.0
5.000000001
5

样例输出

6
5
6
5

代码

#include <iostream>
#include <cmath>
using namespace std;
 
// 函数用于将实数转换为大于等于它的整数
int ceil_to_integer(double x) {
    return static_cast<int>(ceil(x));
}
 
int main() {
    int N;
     
    cin >> N;
 
    for (int i = 0; i < N; ++i) {
        double A;
        cin >> A;
        cout << ceil_to_integer(A) << endl;
    }
 
    return 0;
}

问题 J: 内码对称

时间限制: 1 Sec 内存限制: 128 MB

题目描述

C++中int型整数内码是一个32位的01序列,该01序列有些是对称的,有些是不对称的。对于给定的一个整数,在一些场合,需要判断其整数内码(去除前导0)的对称性。这个事情要做好还非你不行呢。

输入

输入中含有一些整数n(0≤n<2^32)。输入-1表示输入结束

输出

统计其中一共有多少个其内码对称的整数,输出之。

样例输入

0
1
2147483649
2
3
-1

样例输出

3

代码

#include <iostream>
#include<string.h>
#include<math.h>
using namespace std;
int main()
{
    unsigned int n;
    int sum=0;
    unsigned int num[32];
    int flag,i,size;
    while(true)
    {
        cin >> n;
        if(n == -1){
            break;
        }
        flag=1;
        size =0;
        if(n==0){
            continue;
        } 
            while(n!=0){
                num[size] = n%2;
                n/=2;
                size++;
            }
            for(int i =0; i <size; ++i){
                if(num[i] != num[size-i-1] ){
                    flag=0;
                    break;
                }
            }
            if(flag==1){
                sum++;
            }
                 
    }
    cout << sum << endl;
    return 0;
 } 

问题 K: 统计立方数

时间限制: 1 Sec 内存限制: 128 MB

题目描述

有一堆正整数,统计其中有多少立方数。

输入

输入数据有一些正整数,其每个数都小于2^32。若该数为0,则应结束统计。

输出

输出所统计的立方数个数。

样例输入

1 3 5 7 9 11 15 17 19 21 23 25 27 0

样例输出

2

代码

#include <iostream>
#include <cmath> // 用于pow和sqrt函数
 
int main() {
    int number, count = 0;
    while (true) {
        std::cin >> number;
        if (number == 0) break; // 如果输入0,则结束循环
        // 计算立方根,然后检查是否为整数
        if (std::round(std::cbrt(number)) * std::round(std::cbrt(number)) * std::round(std::cbrt(number)) == number) {
            count++; // 如果是立方数,增加计数
        }
    }
    std::cout << count << std::endl; // 输出立方数的个数
    return 0;
}

问题 L: DNA的形状

时间限制: 1 Sec 内存限制: 128 MB

题目描述

grass从小就喜欢生命科学,他总是好奇花草鸟兽从哪里来的。终于, grass上中学了,接触到了神圣的名词–DNA.它有一个双螺旋的结构。 这让一根筋的grass抓破头皮,“要是能画出来就好了” grass喊道。 现在就请你帮助他吧! _

输入

输入包含多组测试数据。第一个整数N(N<=15),N表示组数,每组 数据包含两个整数a,b。a表示一个单位的DNA串的行数,a为奇数且 3<=a<=39。b表示重复度(1<=b<=20)。

输出

输出DNA的形状,每组输出间有一空行。

样例输入

2
3 1
5 4

样例输出

X X
 X
X X

X   X
 X X
  X
 X X
X   X
 X X
  X
 X X
X   X
 X X
  X
 X X
X   X
 X X
  X
 X X
X   X

代码

#include <iostream>
using namespace std;
 
int main() {
    int N,a,b;
    cin >> N;
       while(N--){
        cin >> a >> b;
        if(a<3 || a > 39|| b<1 || b >20 || a%2==0){
            break;
        }
        else{
            while(b--){  //重复次数 
                for(int i=0; i<a-1 ; i++){  //重复行输出 
                     for(int j=0 ; j <a ; j++){  //重复列输出 
                        if(i==j){
                            cout << "X";
                        }
                        else if(i==a-j-1){
                            cout << "X";
                        }
                        else{
                            cout << " ";
                        }
                     }
                     cout << endl;
                }
                if(b==0){
                        for(int i=0; i<a;i++){
                        if(i==0){
                            cout << "X";
                        }
                        else if(i==a-1){
                            cout << "X"<<endl;
                        }
                        else{
                            cout << " ";
                        }
                }
                }
             
            }
             cout << endl;
        }
    }
    return 0;
}

问题 M: 剪花布条

时间限制: 1 Sec 内存限制: 128 MB

题目描述

一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢?

输入

输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。

输出

输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间应换行。

样例输入

abcde a3
aaaaaa  aa
#

样例输出

0
3

代码

#include <iostream>
#include <string>
using namespace std;
 
int main() {
   string str1,str2;
   int len1,len2,count;
   while(true){
        cin >> str1;
        if(str1 == "#"){
            break;
        }
        cin >> str2;
        count =0;
        len1 = str1.size();
        len2 = str2.size();
         
        for(int i=0; i<= len1-len2;){
            if(str1.substr(i,len2) == str2){
                count++;
                i+=len2;
            }else{
                i++;
            }
        }
        cout << count << endl;
         
        str1.clear();
        str2.clear();
   }
    
    return 0;
}

问题 N: 不要62

时间限制: 1 Sec 内存限制: 128 MB

题目描述

杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。

杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。

不吉利的数字为所有含有4或62的号码。例如:

62315 73418 88914

都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。

你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。

输入

输入的都是整数对n、m(0<n≤m<1000000),如果遇到都是0的整数对,则输入结束。

输出

对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。

样例输入

1 100
0 0

样例输出

80

代码

#include <iostream>
#include <string>
using namespace std;
 
 
bool islaoer(int num){
    int sixNum=0,twoNum=0;
    while(num){
        sixNum = num/10%10;
        twoNum = num%10;
        num/=10;
        if(twoNum==4 || sixNum == 4 || (sixNum==6 && twoNum==2)){
            return true;
        }
    }
    return false;
}
 
int main() {
     
    int n,m,count;
    while(true){          
      cin >> n >> m;
      count =0;
      if(n==0&&m==0 ){
        break;
      }
      else if( n <=0 && m>1000000 || n>m){
        break;
      }
      else{
        for(int i=n; i<=m;++i){
            if(!islaoer(i)){
                count++;
            }
        }
      }
        cout << count << endl;
    }
   
 
     
    
    return 0;
}

问题 O: 过原点的直线数

时间限制: 1 Sec 内存限制: 128 MB

题目描述

给定平面上P个点(0< P < 70000),每个点p的坐标均为整数,且0<=x,y<1000。
求整个平面,通过点p和原点,可以构造出多少条过原点(0,0)的直线。没有任意两点具有相同坐标。

输入

输入第一行为N,表示测试数据的组数。接下来有N组测试数据。每组测试数据第一行为P,接下P行每行2个整数,分别指定了该点的坐标X、Y值。

输出

输出为N行,每行一个整数,表明该组测试数据存在过原点(0,0)直线的条数。

样例输入

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

样例输出

3

代码

#include <stdio.h>
#include <stdlib.h>
  
typedef struct {
    int x;
    int y;
} Point;
  
// 求最大公约数
int gcd(int a, int b) {
    if (b == 0) return a;
    return gcd(b, a % b);
}
  
// 求点a和原点的直线斜率
long long get_slope(Point a) {
    if (a.x == 0) return 1001; // 任何一个斜率大于1000的都不会出现
    int common_factor = gcd(abs(a.x), abs(a.y));
    return ((long long)a.y / common_factor) * 1001 + (long long)a.x / common_factor;
}
  
int main() {
    int N;
    scanf("%d", &N);
  
    while (N--) {
        int P;
        scanf("%d", &P);
  
        // 存储斜率的集合
        int *slopes = (int *)calloc(P, sizeof(int));
  
        // 读取点并计算斜率
        for (int i = 0; i < P; ++i) {
            Point point;
            scanf("%d %d", &point.x, &point.y);
            slopes[i] = get_slope(point);
        }
  
        // 统计不同斜率的数量
        int unique_slopes = 0;
        for (int i = 0; i < P; ++i) {
            int j;
            for (j = 0; j < i; ++j) {
                if (slopes[i] == slopes[j]) break;
            }
            if (i == j) ++unique_slopes;
        }
  
        printf("%d\n", unique_slopes);
  
        free(slopes);
    }
  
    return 0;
}

问题 P: 数的计数

时间限制: 1 Sec 内存限制: 128 MB

题目描述

我们要求找出具有下列性质数的个数(包含输入的自然数nn)。
先输入一个自然数 n(n≤1000),然后对此自然数按照如下方法进行处理:
1· 不作任何处理;
2. 在它的左边加上一个自然数,但该自然数不能超过原数的一半;
3. 加上数后,继续按此规则进行处理,直到不能再加自然数为止。

输入

自然数n

输出

满足条件的数的个数

样例输入

6

样例输出

6

提示
满足条件的数为 6 (此部分不必输出),他们分别是:
(1)6
(2)16
(3)26
(4)126
(5)36
(6)136

代码

#include <iostream>
#include <vector>
  
// 函数用于计算给定数字的满足条件的数的个数
int countNumbers(int n, std::vector<int>& memo) {
    // 如果已经计算过这个数字,直接返回它的计数
    if (memo[n] != -1) {
        return memo[n];
    }
  
    int total = 1; // 当前数字本身应该被计算在内
  
    // 遍历所有可能添加的数字
    for (int i = 1; i <= n / 2; ++i) {
        // 对于每个可能的数字,递归计算并累加结果
        total += countNumbers(i, memo);
    }
  
    // 存储当前数字的计数,并返回
    memo[n] = total;
    return total;
}
  
int main() {
    int n;
    std::cin >> n;
  
    // 初始化记忆化数组,-1 表示未计算
    std::vector<int> memo(n + 1, -1);
  
    // 计算并输出结果
    std::cout << countNumbers(n, memo) << std::endl;
  
    return 0;
}

问题 Q: 排列

时间限制: 1 Sec 内存限制: 128 MB

题目描述

Ray又对数字的列产生了兴趣: 现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数

输入

第一行是一个整数N,表示数据的组数。 每组数据占一行,代表四张卡片上的数字(保证四个数字都不同,且0<数字<10)。

输出

对每组卡片按从小到大的顺序输出所有能由这四张卡片组成的4位数,千位数字相同的在同一行,同一行中每个四位数间用空格分隔,每组输出数据间空一行,最后一组数据后面没有空行。

样例输入

2
1 2 3 4
1 2 3 5

样例输出

1234 1243 1324 1342 1423 1432
2134 2143 2314 2341 2413 2431
3124 3142 3214 3241 3412 3421
4123 4132 4213 4231 4312 4321

1235 1253 1325 1352 1523 1532
2135 2153 2315 2351 2513 2531
3125 3152 3215 3251 3512 3521
5123 5132 5213 5231 5312 5321

代码

#include <stdio.h>
  
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}
  
  
int main() {
    int N;
    scanf("%d", &N);
    while (N--) {
        int arr[4];
        for (int i = 0; i < 4; i++) {
            scanf("%d", &arr[i]);
        }
          
        // 对数组进行排序
        for (int i = 0; i < 3; i++) {
            for (int j = i + 1; j < 4; j++) {
                if (arr[i] > arr[j]) {
                    swap(&arr[i], &arr[j]);
                }
            }
        }
          
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                for (int k = 0; k < 4; k++) {
                    for (int l = 0; l < 4; l++) {
                        if (i != j && i != k && i != l && j != k && j != l && k != l) {
                            printf("%d%d%d%d ", arr[i], arr[j], arr[k], arr[l]);
                        }
                    }
                }
            }
            printf("\n");
        }
        printf("\n");
    }
    return 0;
}

问题 R: 排列2

时间限制: 1 Sec 内存限制: 128 MB

题目描述

Ray又对数字的列产生了兴趣: 现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数。

输入

每组数据占一行,代表四张卡片上的数字(0<=数字<=9),如果四张卡片都是0,则输入结束。

输出

对每组卡片按从小到大的顺序输出所有能由这四张卡片组成的4位数,千位数字相同的在同一行,同一行中每个四位数间用空格分隔。 每组输出数据间空一行,最后一组数据后面没有空行。

样例输入

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

样例输出

1234 1243 1324 1342 1423 1432
2134 2143 2314 2341 2413 2431
3124 3142 3214 3241 3412 3421
4123 4132 4213 4231 4312 4321

1123 1132 1213 1231 1312 1321
2113 2131 2311
3112 3121 3211

1023 1032 1203 1230 1302 1320
2013 2031 2103 2130 2301 2310
3012 3021 3102 3120 3201 3210

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
  
int main()
{
    char a[4]={0};
    int x=0;
    while(1)
    {
        for(int i=0;i<4;i++)
        {
            cin>>a[i];
        }
        sort(a,a+4);
        char w=a[0];
        if(a[0]=='0'&&a[1]=='0'&&a[3]=='0'&&a[2]=='0') break;
        if(x) cout<<endl;
        x++;
        int qt=0;
        int lasta0=-1;
        bool flag2=true;
       do {
            if(a[0]=='0')continue;
            if(flag2)flag2 = false;
            else if(a[0] == lasta0) cout<<' ';
            else  cout<<endl;
           cout<<a[0]<<a[1]<<a[2]<<a[3];
            lasta0 = a[0];
        } while(next_permutation(a, a +4));
        cout<<endl;
    }
    return 0;
}

问题 S: 最多拦截导弹数

时间限制: 1 Sec 内存限制: 128 MB

题目描述

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它能拦截任意高度的导弹,但是每拦截一发导弹,其拦截能力就下降到只能拦截上一次拦截的导弹高度,遇到无法拦截的导弹高度,则停止拦截。
某天,雷达捕捉到敌国的导弹来袭,导弹依次飞来,该拦截系统最多能拦截多少导弹呢?

输入

输入若干组数据。每组数据包括:导弹总个数(正整数<1000),导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数,用空格分隔)。若导弹个数为0,则处理结束

输出

输出这套系统最多能拦截多少导弹。

样例输入

8
3890  2070  1550  3000  2990  1700  1580  650
0

样例输出

3

代码

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
using namespace std;
  
int main(void)
{
    int n,m,count,height,judge,judge2;
    int arr[10000];
    while(1){
        count=0;
        judge2=0;
        judge=0;
        scanf("%d",&n);
        if(n==0){
            break;
        }
        for(int i=0;i<n;i++){
            scanf("%d",&arr[i]);
        }
          
        for(int i=0;i<n;i++){
            m=arr[i];
            if(judge==0){
                judge=1;
                height=m;
                count++;
                continue;
            }
            if(m<=height){
                height=m;
                count++;
            }else{
                judge2=1;
                printf("%d\n",count);
                break;
            }
        }
        if(judge2){
            continue;
        }
          
          
          
    }
}

问题 T: 昊城的分割游戏

时间限制: 1 Sec 内存限制: 128 MB

题目描述

昊城国庆假期发明了一款小游戏:

给定1,2,…,n-1, n的n个正整数,要把这n个数,分割为2部分,其中一部分包含在A集合中,另外的包含在B集合中。

假设A集合中所有数的累加和为SA, B集合中所有数的累加和为SB,

目标是找到这样一种分割,使得SA和SB的差值最小,即|SA-SB|达到最小值。

请输出这个最小值。

输入

输入正整数n, 1<=n<=2*10^9

输出

输出|SA-SB|的最小值

样例输入

样例1输入+
3
样例2输入
5
样例3输入
6

样例输出

样例1输出
0
样例2输出
1
样例3输出
1

代码

#include <iostream>
using namespace std;
int main(){
 
    int n,sum=0;
    cin >> n;
    for(int i=1; i<=n ;++i){
        sum+=i;
    }
 
    if(sum%2==0){
        cout << 0 << endl;
    }
    else{
        cout << 1 << endl;
    }
    return 0;
}
  • 21
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值