2025年寒假ACM练习1

A: 计算球体积

根据输入的半径值,计算球的体积。

输入

输入数据有多组,每组占一行,每行包括一个实数,表示球的半径。

输出

输出对应的球的体积,对于每组输入数据,输出一行,计算结果保留三位小数。

样例输入 Copy
1
1.5
样例输出 Copy
4.189
14.137
提示

#define PI 3.1415927

#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <algorithm>
#include <cstring>
#include <vector>
#include <unordered_map>
#define p 3.1415927
using namespace std;
typedef long long ll;
const int N = 1e6 +5;
const int M = 1e9 +7;
const int inf = 0x3fffffff;
void solve(){
    double r,v;
    while(cin>>r){       
        v=4.0/3*p*r*r*r;
        printf("%.3f\n",v);
    }
}
int main() {
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    //int t;cin>>t;while(t--)
    solve();
    return 0;
}

 B: 成绩转换

输入一个百分制的成绩t,将其转换成对应的等级,具体转换规则如下:
90~100为A;
80~89为B;
70~79为C;
60~69为D;
0~59为E;

输入

输入数据有多组,每组占一行,由一个整数组成。

输出

对于每组输入数据,输出一行。如果输入数据不在0~100范围内,请输出一行:“Score is error!”。

样例输入 Copy
56
67
100
123
样例输出 Copy
E
D
A
Score is error!
#include<stdio.h>
int main() {
    int a, b;
    while (scanf("%d", & a) != EOF) {
        if (a > 100 || a < 0)
            printf("Score is error!\n");
        else {
            b = a / 10;
            switch (b) {
                case 10:
                case 9:
                    printf("A\n");
                    break;
                case 8:
                    printf("B\n");
                    break;
                case 7:
                    printf("C\n");
                    break;
                case 6:
                    printf("D\n");
                    break;
                default:
                    printf("E\n");
            }
        }
    }
    return 0;
}

 C: 求奇数的乘积

给你n个整数,求他们中所有奇数的乘积。

输入

输入数据包含多个测试实例,每个测试实例占一行,每行的第一个数为n,表示本组数据一共有n个,接着是n个整数,你可以假设每组数据必定至少存在一个奇数。

输出

输出每组数中的所有奇数的乘积,对于测试实例,输出一行。

样例输入 Copy
3 1 2 3
4 2 3 4 5
样例输出 Copy
3
15
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <algorithm>
#include <cstring>
#include <vector>
#include <unordered_map>
using namespace std;
typedef long long ll;
const int N = 1e6 +5;
const int M = 1e9 +7;
const int inf = 0x3fffffff;
void solve(){
    int a,b,s;
    while(cin>>a){
        s=1;
        while(a--){
            scanf("%d",&b);
            if(b%2!=0)
               s*=b;
        }
        printf("%d\n",s);
    }
}
int main() {
    //ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    //int t;cin>>t;while(t--)
    solve();
    return 0;
}

 D: 平方和与立方和

给定一段连续的整数,求出他们中所有偶数的平方和以及所有奇数的立方和。

输入

输入数据包含多组测试实例,每组测试实例包含一行,由两个整数m和n组成。

输出

对于每组输入数据,输出一行,应包括两个整数x和y,分别表示该段连续的整数中所有偶数的平方和以及所有奇数的立方和。
你可以认为32位整数足以保存结果。

样例输入 Copy
1 3
2 5
样例输出 Copy
4 28
20 152
#include <iostream>
#include <string>
#include <cmath>
#include <set>
#include <algorithm>
#include <cstring>
#include <vector>
#include <unordered_map>
using namespace std;
typedef long long ll;
const int N = 1e6 +5;
const int M = 1e9 +7;
const int inf = 0x3fffffff;
void solve(){
    int m,n,i,x,y;
    while(scanf("%d%d",&m,&n)!=EOF){
        x=0;y=0;
        if(m>n){
            for(i=n;i<=m;i++){
                if(i%2==0)
                    x=x+i*i;
                else
                    y=y+i*i*i;
            }
        }
        else{
            for(i=m;i<=n;i++)
            {
                if(i%2==0)
                    x=x+i*i;
                else
                    y=y+i*i*i;
            }
        }
        printf("%d %d\n",x,y);
    }
}
int main() {
    //ios::sync_with_stdio(0);cin.tie(0);
    //int t;cin>>t;while(t--)
    solve();
    return 0;
}

 E: 水仙花数

春天是鲜花的季节,水仙花就是其中最迷人的代表,数学上有个水仙花数,他是这样定义的:
“水仙花数”是指一个三位数,它的各位数字的立方和等于其本身,比如:153=1^3+5^3+3^3。
现在要求输出所有在m和n范围内的水仙花数。

输入

输入数据有多组,每组占一行,包括两个整数m和n(100<=m<=n<=999)。

输出

对于每个测试实例,要求输出所有在给定范围内的水仙花数,就是说,输出的水仙花数必须大于等于m,并且小于等于n,如果有多个,则要求从小到大排列在一行内输出,之间用一个空格隔开;
如果给定的范围内不存在水仙花数,则输出no;
每个测试实例的输出占一行。

样例输入 Copy
100 120
300 380
样例输出 Copy
no
370 371
#include<stdio.h>
int main()
{
    int m,n,s,i,a,b,c;
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        s=0;
        for(i=m;i<=n;i++)
        {
            a=i/100;
            b=i/10%10;
            c=i%10;
            if(a*a*a+b*b*b+c*c*c==i)
            {
                printf("%d ",i);
                s++;
            }
        }
        if(s!=0)
            printf("\n");
        if(s==0)
            printf("no\n");
    }
    return 0;
}

 F: 母牛的故事

有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?

输入

输入数据由多个测试实例组成,每个测试实例占一行,包括一个整数n(0 n=0表示输入数据的结束,不做处理。

输出

对于每个测试实例,输出在第n年的时候母牛的数量。
每个输出占一行。

样例输入 Copy
2
4
5
0
样例输出 Copy
2
4
6
#include<stdio.h>
int m(int n)
{
    if(n<=4)
    return n;
    else
    return (m(n-1)+m(n-3));
}
int main()
{
    int n,s;
    while(scanf("%d",&n)!=EOF)
    {
        s=m(n);
        if(s!=0)
        printf("%d\n",s);
    }
    return 0;
}   

 G:十六进制回文数

小米在学习进制转换,今天学习的内容是十进制和十六进制之间的转换。
小米突然想到一个问题,有没有一些十进制正整数,它本身不是回文数,但是转成十六进制(去掉前导0)之后会变成回文数呢?
回文数是指那些从左往右和从右往左读都相同的数字,例如12321、ABBA等。十六进制中包含0-9以及A、B、C、D、E和F一共16个字符。
现在请你编写一个程序,统计在十进制正整数M和十进制正整数N之间(1<=M<N<=1000000)有多少个满足要求的数字(本身不是回文数,转成十六进制并去掉前导0之后会变成回文数)?如果在M和N之间一个满足要求的数字都没有则输出0。
【注意:一位数也是回文数。】

输入

单组输入。
输入两个十进制正整数M和N,1<=M<N<=1000000。两者之间用英文空格隔开。

输出

输出在M和N之间(包括M和N),满足本身不是回文数,但是转成十六进制并去掉前导0之后会变成回文数的数字的个数。如果在M和N之间一个满足要求的数字都没有则输出0。

样例输入 Copy
1 20
样例输出 Copy
6
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
bool fun1(string s)
{
  int n = s.size();
  for (int i = 0; i < n / 2; i++)
    if (s[i] != s[n - i - 1])
      return false;
  return true;
}
string fun2(int n)
{
  string s = "";
  while (n > 0)
  {
    int t = n % 16;
    if (t < 10)
      s += (char)(t + '0');
    else
      s += (char)(t - 10 + 'A');
    n /= 16;
  }
  reverse(s.begin(), s.end());
  return s;
}
int main()
{
  int m, n;
  cin >> m >> n;
  int sum = 0;
  for (int i = m; i <= n; i++)
    if (!fun1(to_string(i)) && fun1(fun2(i)))
      sum++;
  cout << sum << endl;
  return 0;
}

 H: lsx的立方体

给你一个边长为n的立方体。求立方体空间内可构成等边三角形的数目。等边三角形每边必须平行于oxy、oxz、oyz的某个表面,每个点只能在立方体的边界或内点上,每个点的三个坐标x、y、z必须是整数。

样例输入 Copy
1
样例输出 Copy
8
#include<stdio.h>
#include<math.h>
int main()
{
    int n,sum=0,i;
    while(~scanf("%d",&n))
    {
        for(i=1;i<=n;i++)
        {
            sum+=pow(n-i+1,3);
        }
        printf("%d\n",sum*8);
    }
    return 0;
}

 I: X星切糕

据说在X星上有一种切糕,这种切糕呈细长形状,并且按长度来进行售卖。
更有意思的是,不同长度的切糕其价格不一样。定价规则如下:
1单位长度:价值为3枚X星币。
2单位长度:价值为7枚X星币。
3单位长度:价值为11枚X星币。
4单位长度:价值为15枚X星币。
5单位长度:价值为20枚X星币。
现有一块N个单位长度的切糕,需要将其切成若干小段,每一小段的长度均不超过5个单位长度,请问可以得到的最大价值是多少枚X星币?

输入

单组输入。
输入一个正整数N表示切糕的总长度,N<=10^6。

输出

输出切成小段之后可以得到的最大价值(X星币的枚数)。

样例输入 Copy
12
样例输出 Copy
47
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e3 + 5;
void solve(){
    int n,s;
    cin>>n;
    s=20*(n/5);
    n%=5;
    if(n==4)
        s+=15;
    else if(n==3)
        s+=11;
    else if(n==2)
        s+=7;
    else if(n==1)
        s+=3;
    cout<<s<<"\n";
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    solve();
    return 0;
}

 J: 字符串变换

Kimi同学需要对一个全部由英文字母组成的字符串进行变换,其变换规则如下:
(1) 原始字符串的总长度为N,每次从左到右取长度为M(2<=M<=N)的子字符串进行变换;如果剩余字符串长度不到M,则取剩余全部字符串进行变换。
(2) 每次取长度为M的子字符串进行变换时需要将子串中的小写字母全部改为大写字母,然后反转该子串。
请编写一个程序帮助Kimi实现上述字符串变换,输出变换之后的字符串。

输入

单组数据。
第1行输入两个正整数N和M,N表示原始字符串的长度,N<=1000;M表示每次变换时所取的子串长度,2<=M<=N。
第2行输入一个长度为N,且只包含大写和小写英文字母的字符串。

输出

输出变换之后的字符串。

样例输入 Copy
10 4
ABcdACbbEA
样例输出 Copy
DCBABBCAAE
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main() 
{
    int n, m;
    cin >> n >> m;
    string s;
    cin >> s;
    for (int i = 0; i < n; i += m) 
    {
        int sum = min(i + m, n);
        for (int j = i; j < sum; j++)
            if (islower(s[j]))
                s[j] = toupper(s[j]);
        reverse(s.begin() + i, s.begin() + sum);
    }
    cout << s << endl;
    return 0;
}

 K: 评分计算器

某电子商务网站对于商家的评价体系是1-5星评价体系,用户在完成订单之后可以对商家打1/2/3/4/5星,而在客户端上,商家的评级却不一定是整数,而是会显示小数点后的一位。很显然这就需要一个计算器了,小明拥有了一些商户的评价数据,希望可以计算出商家在客户端上显示出的评分。 
这个评分的计算非常简单,就是对该商家的所有客户的星级评价做求一个平均,然后去尾法显示小数点后的一位即可,例如平均得分是3.55,则显示的是3.5。例如某商家获得了1-5星评价各一个,则显示的评分是(1+2+3+4+5)/5=3.0。
如果商家没有获得评价,则显示0.0。  

输入

输入包含5个整数,依次分别表示商家获得1星到5星的评价数量,每一种评价的数量都不大于1000。

输出

输出仅包含一个保留一位的小数,表示商家在客户端上显示的评级。

样例输入 Copy
2 2 1 1 2
样例输出 Copy
2.8
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e3 + 5;
void solve(){
    int a,b,c,d,e;
    double s;
    scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);
    if(a+b+c+d+e==0)
        printf("0.0\n");
    else{
        s=(double)(a+2*b+3*c+4*d+5*e)/(a+b+c+d+e);
        s=(double)((int)(s*10))/10;
        printf("%.1f\n",s);
    }
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    solve();
    return 0;
}

 L: 缩页

某文本编辑软件的打印功能可以根据输入的页码来打印所需的页面。有时用户会输入“1,2,3,1,1,5,6”,但是实际上需要的打印的只有“1-3,5-6”这五页,这时就需要软件对用户输入的页码进行处理。

现在请你将用户输入的页码表示为l1-r1,l2-r2……的形式,如果li=ri,则只输出li即可,中间用逗号隔开。

输入
输入第一行包含若干个整数,最少一个,最多100000个,中间用逗号隔开(页号不大于100000)。
输出

输出包含若干个形如li-ri形式的页码段,中间用逗号隔开。

样例输入 Copy

1,2,3,1,1,2,6,6,2

样例输出 Copy
1-3,6
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int a[1000005];
int main()
{
  string s;
  getline(cin, s); 
  int n = 0;
  for (int i = 0; i < s.size(); i++)
  { 
    if (s[i] == ',')
      continue;    
    int j = i, t = 0; 
    while (j < s.size() && s[j] != ',')
    {                  
      t = t * 10 + s[j] - '0'; 
      j++;
    }
    a[n++] = t; 
    i = j;       
  }
  sort(a, a + n);       
  n = unique(a, a + n) - a;
  int x = a[0],y = a[0];          
  for (int i = 1; i < n; i++)
  { 
    if (a[i] == y + 1)
      y = a[i];
    else
    {
      if (x == y)
        cout << x;
      else
        cout << x << "-" << y;
      cout << ",";
      x = a[i];
      y = a[i];
    }
  }
  if (x == y)
    cout << x;
  else
    cout << x << "-" << y;
  return 0;
}

 M: 扑克牌接龙游戏

小明最近喜欢上了一种非常简单的扑克牌接龙游戏。
游戏的玩法是这样的:
将扑克牌洗牌后平均分为两堆,每人轮流出一张牌进行接龙。如果某个人出的牌的大小和接龙牌堆中一张已有牌的大小相同(不考虑花色),那么他可以将这两张牌以及中间所有的牌全部收走并据为己有。例如:如果在接龙的牌堆中有一个3,你再出一个3,那么这两个3以及它们中间的牌都归你所有。

两个人依次出牌,最后比谁收到的牌最多即可获胜。

我们把这个问题稍作简化,如果是一个人在玩这个游戏。现在给你一串数字和字母表示扑克牌的次序,请问最多的一次可以收走多少张牌。

输入

单组输入,输入占两行。
第1行是牌的总数n。(n<=1e5) 
第2行输入n个数字或者字符(对应2、3、4、5、6、7、8、9、10和A、J、Q、K),两两之间用空格隔开。

输出

输出一个整数,即最多一次可以收走的牌数。

样例输入 Copy
11
A 2 3 3 4 3 2 2 3 4 A
样例输出 Copy
5
提示

样例解释:当出第4张“3”时,可以收走第3张“3”和第4张“3”,共收走2张牌;当出第7张“2”时,可以收走第2张“2”以及第5张到第7张牌,即一共收走了“2,4,3,2”,共收走4张牌;当出第11张“A”时,可以收走第1张“A”和第8张到第11张牌,即一共收走了“A,2,3,4,A”,共收走5张牌。因此最多的一次收走5张牌。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
void solve(){
    int n, m = 0;
    vector<string> s;
    cin >> n;
    while (n--)
    {
        string a;
        cin >> a;
        if (s.size())
        {
            if (find(s.begin(), s.end(), a) != s.end())
            {
                int k = 1;
                while (find(s.begin(), s.end(), a) != s.end())
                {
                    s.pop_back();
                    k++;
                }
                m = max(m, k);
            }
            else
                s.push_back(a);
        }
        else
            s.push_back(a);
    }
    cout << m << "\n";
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    solve();
    return 0;
}

 N: 重复单词

小米的电脑这几天出了一点问题:在输入英文的时候,有一些单词会莫名其妙地在单词的后面重复一次。
例如:输入“Who are you”,有时候会变成“Who are are you”。
你能否编写一个程序帮助小米去掉那些相邻的、重复出现的单词中的第二个单词?
注意:(1) 为了对问题进行简化,在输入数据中均不包含标点符号;(2) 单词之间统一用一个英文的空格隔开;(3) 单词不区分大小写,即"Who"和"who"当做同一个单词看待;(4) 不需要考虑输入数据中本身存在两个单词重复的情况,即只要出现单词重复都需要去掉第二个;(5)对于多个连续出现的重复单词,只需要保留第一个。

输入

单组输入。
输入一个长度不超过1000的字符串,该字符串由若干个英文单词和英文空格组成。

输出

输出按照要求去掉重复单词之后的字符串。

样例输入 Copy
Who are Are you
样例输出 Copy
Who are you
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e3 + 5;
void solve(){
    string s,s1,s2,s3;
    getline(cin,s);
    for(int i=0;i<s.size();i++){
        s1+=s[i];
        if(s[i]==' '){
            for(int j=0;j<s1.size();j++)
                if('a'<=s1[j]&&s1[j]<='z') s2+=s1[j];
                else s2+=s1[j]+32;
            if(s2!=s3) cout<<s1;
            s3=s2;
            s1=s2="";
        }
    }
    s1+=' ';
    for(int j=0;j<s1.size();j++)
                if('a'<=s1[j]&&s1[j]<='z') s2+=s1[j];
                else s2+=s1[j]+32;
    if(s2!=s3) cout<<s1<<'\n';
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    solve();
    return 0;
}

O: 互异字符串

请实现一个算法,确定一个字符串的所有字符是否全都不同。

给定一个字符串,请返回一个True代表所有字符全都不同,False代表存在相同的字符。

输入

输入一个字符串。保证字符串中的字符为ASCII字符。字符串的长度小于等于3000。

输出

 如果所有字符全都不同输出“True”,如果存在相同的字符则输出“False”。

样例输入 Copy
aeiou
BarackObama
样例输出 Copy
True
False
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
int fun(string a)
{
    sort(a.begin(),a.end());
    for(int i=0;i<a.length();i++)
        if(a[i]==a[i+1])
            return 0;
    return 1;
}
void solve(){
    string a;
    while(cin>>a)
        if(fun(a)==1)
            cout<<"True\n";
        else
            cout<<"False\n";
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    solve();
    return 0;
}

P: 第k个数

有一些数的素因子只有3、5、7,请设计一个算法,找出其中的第k个数。

输入

给定一个正整数k,保证k小于等于100。

输出

输出第k个数。

样例输入 Copy
1
3
4
5
样例输出 Copy
3
7
9
15
#include<iostream>
using namespace std;
int main()
{
    int k,a[1024];
    while(cin>>k)
    {
        int x=0,y=0,z=0;
        a[0]=1;
        for(int i=1;i<=k;i++)
        {
            a[i]=min(a[x]*3,min(a[y]*5,a[z]*7));
            if(a[i]==a[x]*3)
                x++;
            if(a[i]==a[y]*5)
                y++;
            if(a[i]==a[z]*7)
                z++;
        }
        cout<<a[k]<<endl;
    }
    return 0;
}

Q: 2的个数

请编写一个程序,输出0到n(包括n)中数字2出现了几次。

输入

输入一个正整数n。

输出

输出0到n的数字中2出现了几次。

样例输入 Copy
2
10
20
样例输出 Copy
1
1
3
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e3 + 5;
int a[N];
void solve(){
    int a;
    while(cin>>a)
    {
        int s=0;
        for(int i=0;i<=a;i++)
        {   
            int j=i;
            while(j>0)    
            {
                if(j%10==2)
                    s++;
                j/=10;
            }   
        }
        cout<<s<<"\n";
    }
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    solve();
    return 0;
}

 R: 外星人的语言

Kimi费了很大劲,终于和地外文明联系上。
我们地球人通常有10根手指,因此我们习惯用10进制的数,而外星人的手指有16跟、8根等不等的数目,因此他们使用与我们不同的进制。
为了方便沟通,需要你开发一款工具,把地球人的10进制转换成外星人的R进制形式。
输入

输入有多行。
每行包括两个正整数n和R,其中2≤R≤16。
输入直到文件结束为止。

输出

对于每个用例,输出n对应的R进制形式。
超过10进制的数,10用A表示、11用B表示,依次类推。

样例输入 Copy
1989 2
1119 16
样例输出 Copy
11111000101
45F
#include<stdio.h>
int main()
{
    int n,s,i,j;
    char a[1000];
    while(~scanf("%d%d",&n,&s))
    {
        j=0;
        while(n>0)
        {
            if(n%s>=0&&n%s<=9)
                a[j]=n%s+'0';
            else
                a[j]=n%s-10+'A';
            n/=s;
            j++;
        }
        for(i=j-1;i>=0;i--)
            printf("%c",a[i]);
        printf("\n");
    }
    return 0;
}

 S: 3n+1猜想

卡拉兹(Callatz)猜想:
对任何一个自然数n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把(3n+1)砍掉一半。这样一直反复砍下去,最后一定在某一步
得到n=1。卡拉兹在1950年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,
结果闹得学生们无心学业,一心只证(3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……
我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过1000的正整数n,简单地数一下,需要多少步(砍几下)才能得到n=1?

输入

每个测试输入包含1个测试用例,即给出自然数n的值。

输出

输出从n计算到1需要的步数。

样例输入 Copy
3
样例输出 Copy
5
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e3 + 5;
void solve(){
    int n;
    while(cin>>n){
        int i;
        for(i=0;n!=1;i++)
            n=(n%2==0)?n/2:(3*n+1)/2; 
        cout<<i<<"\n";
    }
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    solve();
    return 0;
}

 T: 狗狗大决杀

这是 10 月 32 日发生的事情。抽筋流高手布置了一个非常 BT 的作业。他说要在一定时间内把屏幕上的所有小狗布成一条直线。而这个时间非常之短!!!众人大呼 BT,但是抽筋流高手是非常严格的,所以大家只好遵从他的命令。 

众所周知,只有达达的 APM 在 190 以上,所以最后完成作业的只有他一个。他受到了 抽筋流高手的表扬。

然而罗小松觉得不爽,于是他趁达达去 WC 的时候在那一条直线上放了一系列机枪兵, 对可爱的狗狗们进行了残忍的屠杀。

已知个机枪兵有一定的射程。然而这是一种特殊的星际版本,机枪升攻击的时候也 可以升射程!所以每个机枪的射程不一定相同。现在一列狗兵排成直线,一次一个机枪兵打掉一定范围内的所有狗狗,每个狗狗有一个编号,每次给出一个杀伤区间, 其中的小狗将会被全部杀掉。最后,让你统计一共杀了多少个。

 简而言之,给出数轴上 N 条线段,条线段用两个数表示 A , B(-10^9<=A<B<=10^9), 表示从 a 到 b 的一条线段。现在请求出它们覆盖数轴上的多长距离。

输入

第一行:N (N ≤ 20000)。

以后 N 行,行两个数:Ai  Bi 。

输出

一个数,表示覆盖长度 。

样例输入 Copy
3
2 8
-1 1
5 10
样例输出 Copy
10
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e4 + 5;
struct S{
    int x,y;
}a[N];
bool cmp(S a,S b){
    return a.x<b.x;
}
void solve(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i].x>>a[i].y;
    }
    sort(a,a+n,cmp);
    int s=a[0].y;
    int sum=0;
    int t=a[0].x;;
    for(int i=1;i<n;i++){
        if(a[i].x<=s){
            s=max(s,a[i].y);
        }
        else{
            sum+=s-t;
            s=a[i].y;
            t=a[i].x;
        }
    }
    sum+=s-t;
    cout<<sum<<"\n";
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    solve();
    return 0;
}

 U: 折纸

小s很喜欢折纸。

有一天,他得到了一条很长的纸带,他把它从左向右均匀划分为N个单位长度,并且在每份的边界处分别标上数字0~N。

然后小s开始无聊的折纸,每次他都会选择一个数字,把纸带沿这个数字当前所在的位置翻折(假如已经在边界上了那就相当于什么都不做)。

小s想知道M次翻折之后纸带还有多长。

输入

第一行包含两个正整数 N 和 M ,表示纸带的长度和操作的次数。(N ≤ 10^18,M ≤ 3000)。

接下来的一行包含 M 个整数 Di ,其中 Di 表示第 i 次选择的数字。

输出

 输出文件只有一个数字,即纸带最后的长度。  

样例输入 Copy
5 2
3 5
样例输出 Copy
2
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e3 + 5;
ll a[N];
void solve(){
    ll n,m;
    cin>>n>>m;
    ll l=0,r=n;
    for(int i=1;i<=m;i++){
        cin>>a[i];
        for(int j=1;j<i;j++){
            if(a[j]>=a[i]){
                a[i]=2*a[j]-a[i];
            }
        }
        r=max(r,2*a[i]-l);
        l=a[i];
    }
    cout<<r-l<<"\n";
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    solve();
    return 0;
}

 V: 爱的日期

Inter和AMD刚刚在上个学期确定了恋爱关系,但是由于要期末考试,他们没法have a appointment。
所以他们打算在2月14日情人节那天一起出去。恰恰最近疫情爆发,Inter和AMD都被关在机箱里面不准出来。
于是Inter就想找一个普通而又特殊的日子再次和AMD约会。 要是个周五,然后这个周五是当月的20号岂不美哉?
你能帮帮Inter找出当年中既是周5,又是20号的月份吗。(找不到Inter就只能伤心的回去挤牙膏了)

输入

输入包含多组数据,每组数据包含一个正整数year(2000≤year≤9999)。

输出

对应每一组数据,输出所有符合条件的月份,月份之间用空格隔开。
如果当年不存在20号是星期五的月份,就输出一行jiyagao。

样例输入 Copy
2000
2001
2002
样例输出 Copy
10
4 7
9 12
#include<stdio.h>
int w(int y,int m,int d)
{
    int w;
    if(m<3)
    {
        m+=12;
        y--; 
    } 
    w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%7;
    return w;
}
int main()
{
    int y,s,i;
    while(~scanf("%d",&y))
    {
        s=0;
        for(i=1;i<13;i++)
        {
            if(w(y,i,20)==5)
            {
                s++;
                if(s==1)
                    printf("%d",i);
                else
                    printf(" %d",i);
            }
        }
        if(s==0)
            printf("jiyagao\n");
        else
            printf("\n");
    }
    return 0;
}

 W: 乒乓球筐

Kimi有两盒(A、B)乒乓球,有红双喜的、有亚力亚的……现在他需要判别A盒是否包含了B盒中所有的种类,并且每种球的数量不少于B盒中的数量,该怎么办呢?

输入

输入有多组数据。
每组数据包含两个字符串A、B,代表A盒与B盒中的乒乓球,每个乒乓球用一个大写字母表示,即相同类型的乒乓球为相同的大写字母。
字符串长度不大于1000。

输出

每一组输入对应一行输出:如果B盒中所有球的类型在A中都有,并且每种球的数量都不大于A,则输出“Yes”;否则输出“No”。

样例输入 Copy
ABCDFYE CDE
ABCDGEAS CDECDE
样例输出 Copy
Yes
No
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5 + 5;
void solve(){
    string a,b;
    while(cin>>a>>b){
        if(a.size()<b.size()){
            cout<<"No\n";
        }
        else{
            map<char,int> mp1,mp2;
            bool t=false;
            for(int i=0;i<a.size();i++){
                mp1[a[i]]++;
            }
            for(int i=0;i<b.size();i++){
                mp2[b[i]]++;
            }
            for(int i=0;i<b.size();i++){
                if(mp1[b[i]]>0&&mp2[b[i]]<=mp1[b[i]]){
                    t=true;
                }
                else{
                    t=false;
                    break;
                }
            }
            if(t){
                cout<<"Yes\n";
            }
            else{
                cout<<"No\n";
            }
        }
    }
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    solve();
    return 0;
}

 X: 最难的问题

Kimi生活在充满危险和阴谋的年代。为了生存,他首次发明了密码,用于军队的消息传递。假设你是军团中的一名军官,需要把发送来的消息破译出来、并提供给你的将军。
消息加密的办法是:对消息原文中的每个字母,分别用该字母之后的第5个字母替换(例如:消息原文中的每个字母A 都分别替换成字母F),其他字符不变,并且消息原文的所有字母都是大写的。密码中的字母与原文中的字母对应关系如下。
密码字母:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
原文字母:V W X Y Z A B C D E F G H I J K L M N O P Q R S T U

输入

输入包括多组数据,每组数据一行,为收到的密文。
密文仅有空格和大写字母组成。(长度<=1000)

输出

对应每一组数据,输出解密后的明文。

样例输入 Copy
HELLO WORLD
SNHJ
样例输出 Copy
CZGGJ RJMGY
NICE
#include<stdio.h>
#include<string.h>
int main()
{
    char s[1000],i,j;
    while(~scanf("%s",s))
    {
        j=strlen(s);
        for(i=0;i<j;i++)
        {
            if(s[i]==' ')
            {
                printf("\40");
                continue;
            }
            else
            {
                if(s[i]-5<'A')
                {
                    s[i]='Z'+s[i]-'A'-4;
                    printf("%c",s[i]);
                }
                else
                {
                    s[i]-=5;
                    printf("%c",s[i]);
                }
            }
            if(i==j-1)
                printf("\n");
        }
    }
    return 0;
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值