1-50 题解

1-10

1. A + B Problem

#include <iostream>
using namespace std;

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

2. Two Rectangles

#include <iostream>
using namespace std;

int main(){
	int a,b,c,d;
	cin>>a>>b>>c>>d;
	
	int s1=a*b,s2=c*d;
	
	if(s1>=s2) cout<<s1<<endl;
	else cout<<s2<<endl;
	return 0;
} 

3. Bitwise Exclusive Or

#include <iostream>
using namespace std;

int main(){
	int a,b;
	cin>>a>>b;
	cout<<(a^b)<<endl; //公示推导:两边同时亦或
	return 0;
} 

4. The Number of Even Pairs

#include <iostream>
using namespace std;

int main(){
	int n,m;
	cin>>n>>m;
	//除一奇一偶外的情况 奇数抽两个 or 偶数抽两个
	int num1=n*(n-1)/2;
	int num2=m*(m-1)/2;
	cout<<num1+num2<<endl;
	return 0;
}

5. Add Sub Mul

#include <iostream>
using namespace std;

int main(){
	int a,b;
	cin>>a>>b;
	
	int ans=a+b;
	if(a-b>ans) ans=a-b;
	if(a*b>ans) ans=a*b;
	cout<<ans<<endl;
	return 0;
}

6. AtCoder Beginner Contest 999

#include <iostream>
#include <string>
using namespace std;

int main(){
	string str;
	cin>>str;
	
	//当作字符串处理 
	for(int i=0;i<str.size();i++){
		if(str[i]=='1') str[i]='9';
		else if(str[i]=='9') str[i]='1';
	}
	cout<<str<<endl;
	return 0;
}

7. Palindromic Number

#include <iostream>
using namespace std;

int main(){
	int n;
	cin>>n;
	
	int h=n/100; //百位
	int m=n%10;  //个位 
	if(h==m) cout<<"Yes"<<endl;
	else cout<<"No"<<endl; 

	return 0;
}

8. Sandglass2

#include <iostream>
using namespace std;

int main(){
	int n,m;
	cin>>n>>m;
	
	if(n-m<0) cout<<0<<endl;
	else cout<<n-m<<endl;

	return 0;
}

9. Odds of Oddness

#include <iostream>
using namespace std;

int main(){
	int n;
	cin>>n;
	
	int num=(n+1)/2; //奇数个数
	double ans=(double)num/n;
	
	printf("%.10lf",ans); 

	return 0;
}

10. ∵∴∵

#include <iostream>
#include <string>
using namespace std;

int main(){
	string s1,s2;
	cin>>s1>>s2;
	
	string str="";
	int len1=s1.size(),len2=s2.size();
	
	for(int i=0;i<len2;i++){
		str+=s1[i];  //奇数位 
		str+=s2[i];	 //偶数位 
	}
	
	if(len1>len2) str+=s1[len1-1]; //补上最后一个奇数位 
	
	cout<<str<<endl; 
	return 0;
}

11-20

11. Maritozzo

设置四个字符串变量s1,s2,s3,t,用cin读入题中四个字符串,循环遍历t字符串,按照题中描述用条件分支语句判断当前字符c属于哪一种情况分别做对应操作即可。最终将答案存在ans字符串中,用cout输出。

#include <iostream>							// 标准输入输出必备头文件
#include <string>							// 用string容器必备
using namespace std;						// 想用c++的容器或者算法,又不想写前缀std就要写这句话
int main()									// 主函数,基本上所有正常的c++主程序都要写在main函数体中,返回值为int
{
    string s1,s2,s3,t;						// string可以理解为变量类型,后面定义的理解为string类型的变量即可
    cin >> s1 >> s2 >> s3 >> t;		// cin会把把标准输入流的信息赋给">>"分隔开的几部分(可以是int,string等)
    string ans = "";						// answer的缩写,用来存储答案,初始为空串
    for(int i = 0;i<int(t.size());i++){		// 遍历t字符串,t.size()返回一个无符号整型,
        									// 需要转成int(不转换无法和负数比较)
        char c = t[i];						// c变量存储当前遍历到的t字符串内的字符
        // 以下就是将题中所述的三种情况分开处理
        if(c == '1'){
            ans+=s1;						// 注意,string类型变量可以用加法的运算符进行“字符串拼接”
        }else if(c == '2'){
            ans+=s2;
        }else{
            ans+=s3;
        }
    }
    cout << ans << '\n';					// cout可以将被"<<"分开的几部分放入标准输出流进行输出
    return 0;
}

12. Count Distinct Integers

思路:主要用到了一个标记数组visited,这个数组前n个数初值为1,我们遍历数组中的每个元素,对于遍历到元素之后的元素,如果数值和当前元素相同,将visited数组置为0。简单来说,我们只保留输入的n个数中每一个不同的数第一次出现的位置,而忽略后面出现的位置,即第一次出现为"1",再出现为"0"。这样的话,visited数组的元素和就是不同数字的个数。

注意:不能开1e9大小的数组来记录当前数字是否出现过,因为内存普遍没有这么大,开不了这么大的数组。并且你在求答案的时候也会从1遍历到1e9,会严重超时。

#include <iostream>
using namespace std;

int main()
{
    int n;
    cin >> n;
    int visited[1000];
    int a[1000] = {0};// 看似只初始化了a[0],但是c++会自动对未初始化部分补零
    for(int i = 0;i<n;i++){
        visited[i] = 1;
    }
    for(int i = 0;i<n;i++){
        cin >> a[i];
    }
    // 这是二重循环,第一层循环称为外层循环,第二层循环称为内层循环,外层循环遍历数组a的下标,通过a[i]的方式可以访问数组的每一个元素,
    //内层循环遍历外层循环所对应元素之后的所有元素,如果之后的元素和当前元素相等,将其visited数组值标为0,即忽略重复值
    for(int i = 0;i<n;i++){
        for(int j = i+1;j<n;j++){
            if(a[j] == a[i]) {
                visited[j] = 0;
            }
        }
    }
    int ans = 0;
    // 对visited数组求和就是答案
    for(int i = 0;i<n;i++){
        ans+=visited[i];
    }
    cout << ans << '\n';
    return 0;
}

另一种做法会用到一点算法,先对a数组进行排序,之后设置两个指针,这两个指针一前一后遍历数组,你可以理解成两个变量在遍历数组,前面那个跑得快的变量和后面那个跑得慢的变量都从0起点开始遍历,快的变量每次更新时会先往前迈一步(+1),然后判断快的变量和慢的变量所指向的数组内容相不相等:

  • 若相等,慢变量原地不动,也就是不更新
  • 若不相等,慢变量也向前迈一步(+1),并把快变量对应的值赋给慢变量(这一步不管是否有重复元素都要做,保持算法通用性,你可以思考为什么这样做是对的)

重复以上操作,直到快变量到达数组末尾,此时慢变量的值+1(因为起点是0,所以目前慢变量遍历的数量是其值+1)就是数组中不同元素的个数。另外此时慢变量之后所有的数组元素均为重复值,也就是说,如果你想得到一个没有重复元素的数组,此时慢变量之前的所有数组元素就是你想要的。代码如下:

#include <iostream>
#include <algorithm>			// 如果你想用sort必须include这个头文件
using namespace std;

int main()
{
    int n;
    cin >> n;
    int a[1000] = {0};
    for(int i = 0;i<n;i++){
        cin >> a[i];
    }
    // 对于静态数组来说,sort的用法很简单,第一个参数写数组的起始指针,第二个参数写数组的起始指针+数组长度(注意这个数组长度指的是数组中你要排序部分的长度),即可实现升序排序。内置sort函数比选择排序、冒泡排序高效得多。
    sort(a,a+n);
    int slow = 0,quick = 1;      // quick先跨出第一步,进入循环
    while(quick<n){              // 当满足quick<n时,才进入循环,否则循环结束
        if(a[quick]!=a[slow]){   // 如果快慢指针对应的数值不等,slow++
            slow++;
            a[slow] = a[quick];
        }
        quick++;                 // quick每次必先向前一步
    }
    cout << slow+1 << '\n';     // 因为a的下标从0开始,slow的数值加1才是slow遍历过的数
    return 0;
}

注意:以下两种方法看不懂没关系,好好琢磨一下上面两种方法足矣。

algorithm头文件中自然不可能只有std::sort这一个强大的函数,在此介绍另外一个:std::unique函数。在数组调用sort排序过后,你可以直接调用unique函数,传进去的参数和上面sort的参数一致。这个函数会返回一个指针,代表去重后的数组末尾指针+1(相当于上面的slow+1)。此时答案可以很容易算出来,假设返回的指针存在了p变量里面,用p-a即为答案(指针可以作类似于整数的运算,可以自行思考为什么在这里不用+1)。

再次注意:只有在有序数组中才能调用unique函数进行去重。

#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    int n;
    cin >> n;
    int a[1000] = {0};
    for(int i = 0;i<n;i++){
        cin >> a[i];
    }
    sort(a,a+n);
    int* p = unique(a,a+n);// p为int*类型,如果不懂,请自行学习,能看懂上面的两种方法就足够了
    cout << p-a << '\n';
    return 0;
}

当然了,如果你学的深入一点,你就可能会知道std::set或者是std::unordered_set,众所周知set,也就是集合的特性之一就是不包含重复元素,c++中的set完美符合这一特性,当你把数字放到set中去的时候set会自动帮你去重,最后只要输出得到的集合大小就是答案了。

这里我就不详细放注释了,你如果感兴趣请自查。属于拓展内容。

#include <iostream>
#include <unordered_set>
using namespace std;

int main()
{
    int n;
    cin >> n;
    unordered_set<int> m;
    for(int i = 0;i<n;i++){
        int x;
        cin >> x;
        m.insert(x);
    }
    cout << m.size() << '\n';
    return 0;
}

13. Golden Coins

这题没什么好说的,小学数学题。得出答案并不困难,唯一要注意的一点是,在c++中对于整数做' / '运算会在除不尽时自动向下取整,你可以直观地理解为c++中的整数除法是不带余数的除法。所以你第一眼看到下面的t = n/500,后面又有n -= t500可能会有疑惑,这样n不就恒为零了吗?其实不然。比如n=501,那么c++中的n/500得到的就是1,即t=1,n - t * 500实际上是等于1的,不是0。后面的n/55是一样的道理。

#include <iostream>
using namespace std;

int main()
{
   int n;
   cin >> n;
   int t = n/500;
   n -= t*500;
   cout << t*1000+n/5*5 << '\n';
   return 0;
}

14. Climbing Takahashi

模拟题,只要按照题目当中说的做就好了。详见代码注释。

#include <iostream>
using namespace std;

int main()
{
    int n;
    cin >> n;
    int a[int(1e5)];		// 以题中给出的最大n值作为数组大小
    for(int i = 0;i<n;i++){
        cin >> a[i];
    }
    int ans = a[0];			// ans保存的就是答案,在还未开始攀登之前,ans初始值就是第一个平台高度
    for(int i = 0;i<n-1;i++){	//遍历到第n-1个数就好了,因为最后一个数右侧没有平台了
        if(a[i+1]>a[i]){	// 如果当前平台右侧的平台比当前平台高,就移动过去
            ans = a[i+1];
        }else{				// 否则结束循环,最终的平台高度已经被记录在了ans变量中
            break;
        }
    }
    cout << ans << '\n';
    return 0;
}

15. Quizzes

又是模拟题。以下代码:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    int n,x;
    cin >> n >> x;
    string s;
    cin >> s;
    int ans = x;							// ans记录最终得分,刚开始,ans==x
    for(int i = 0;i<int(s.size());i++){		// 为什么推荐把s.size()转成int前面有说
        if(s[i] == 'x'){					// 如果当前字符为‘x’,并且当前分数大于0,分数-1
            if(ans>0) ans--;
        }else{								// 否则分数+1
            ans++;
        }
    }
    cout << ans << '\n';
    return 0;
}

16. Remove It

很简单的一道题,你不用想着如何维护把去掉等于x的值后的数组,只需要遍历数组元素,把不等于x的元素输出就好。甚至你都不用存给出的数组,边输入边处理即可。

#include <iostream>
using namespace std;
int main()
{
    int n,x;
    cin >> n >> x;
    for(int i = 0;i<n;i++){
        int t;
        cin >> t;
        if(t != x){
            cout << t << ' ';
        }
    }
    return 0;
}

当然,如果你学得快,学会了链表这个数据结构,并且可以灵活使用结构体,想用这题练练手我也不拦着你。等你练完手了,可以看看用c++内置的双向链表std::list怎么来做这道题:

#include <iostream>
#include <list>
using namespace std;

int main()
{
    int n,x;
    cin >> n >> x;
    list<int> lst;
    for(int i = 0;i<n;i++){
        int t;
        cin >> t;
        lst.push_back(t);
    }
    auto it = lst.begin();
    while(it!=lst.end()){
        while(*it == x){
            it = lst.erase(it);
            if(it == lst.end()) break;
        }
        if(it!=lst.end()) it++;
    }
    for(auto x:lst){
        cout << x << " ";
    }
    return 0;
}

还是不加注释了,属于拓展内容。

17. Minor Change

很简单的一道题,只需要在输入后遍历两个字符串的下标,如果某个位置对应的字符不相等,说明要替换,ans+1统计答案即可。

#include <iostream>
#include <string>
using namespace std;

int main()
{
   string a,b;
   cin >> a >> b;
   int ans = 0;
   for(int i = 0;i<int(a.size());i++){
       if(a[i]!=b[i]){
           ans++;
       }
   }
   cout << ans << '\n';
   return 0;
}

18. Magic 3

关键在于题意理解,理解了问题这题就很简单了。题意应该是施法时间>=S秒或者威力<=D的法术均不会对怪物造成伤害。反过来说我们需要判断的是高桥的某一次攻击是否满足施法时间<S秒并且威力>D,如果满足就输出"Yes",如果所有的攻击都不满足条件,那么输出"No"。

#include <iostream>
using namespace std;

int main()
{
    int n,s,d;
    cin >> n >> s >> d;
    int x,y;
    for(int i = 0;i<n;i++){
        cin >> x >> y;
        if(x<s&&y>d){
            cout << "Yes\n";
            return 0;// 在此处直接退出程序,主要是为了避免出了循环之后再多打印一个No
        }
    }
    cout << "No\n";
    return 0;
}

19. ... (Triple Dots)

灵活运用string的方法就不难做,代码如下:

#include <iostream>
#include <string>
using namespace std;

int main()
{
   int k;
   cin >> k;
   string s;
   cin >> s;
   if(int(s.size())<=k){	// 如果s的大小小于等于k,直接输出s
       cout << s << '\n';
   }else{	
       // 如果大于k,调用s的成员函数substr截取前k个字符,substr第一个参数是起始位置,第二个参数是截取的字符个数
       // substr的返回值仍然是一个string,可以直接送入标准输出流打印
       // 别忘了还要打印"..."
       cout << s.substr(0,k) << "..." << '\n';
   }
   return 0;
}

20. Mix Juice

此题不难,关键是你要想到用前面引入的sort函数进行排序,排完序之后,选取前k个水果价格求和就是答案。

#include <iostream>
#include <algorithm>		// 用sort别忘了这个头文件
using namespace std;

int main()
{
    int n,k;
    cin >> n >> k;
    int a[1000];
    for(int i = 0;i<n;i++){
        cin >> a[i];
    }
    sort(a,a+n);
    int ans = 0;
    for(int i = 0;i<k;i++){
        ans+=a[i];
    }
    cout << ans << '\n';
    return 0;
}

当然了,此题还可以用这个数据结构来写。你如果觉得这些题都太简单,比如说这道题完全没难度,你可以手动实现一个堆结构,维护堆的插入和删除。堆分为小顶堆和大顶堆,很明显这题要维护一个小顶堆。我在这里就不实现了,感兴趣可自行查找数据结构中堆的实现。下面是c++内置库里面实现好的堆结构优先队列在本题的应用,在这次题解中不是重点,不再赘述。同样没有注释,因为一两句话说不清楚,想深入了解的话,去学习c++的STL。

#include <iostream>
#include <queue>
using namespace std;
int main()
{
   int n,k;
   cin >> n >> k;
   priority_queue<int,vector<int>,greater<>> q;
   for(int i = 0;i<n;i++){
       int x;
       cin >> x;
       q.push(x);
   }
   int ans = 0;
   for(int i = 0;i<k;i++){
       ans+=q.top();
       q.pop();
   }
   cout << ans << '\n';
   return 0;
}

21-30

21

// 法一

#include<iostream>
using namespace std;

int main(){
    string s1,s2,s3,a[4]={"ABC", "ARC", "AGC","AHC"};
    cin >> s1>>s2>>s3;

    for(int i=0;i<4;i++){
//当前的元素a[i]与s1、s2、s3比较,如果不相等,则输出a[i]并跳出循环
        if(a[i]!=s1 && a[i]!=s2 && a[i]!=s3){
            cout << a[i] << endl;
            break;
        }
    }

    return 0;
}



// 法二
#include<iostream>
using namespace std;

int main(){
    string s1,s2,s3;
    cin >> s1>>s2>>s3;

// 如果s1、s2、s3都不等于"ABC",则输出"ABC"
    if(s1!="ABC" && s2!="ABC" && s3!="ABC"){
        cout << "ABC" << endl;
    }
// 如果s1、s2、s3都不等于"ARC",则输出"ARC"
    else if(s1!="ARC" && s2!="ARC" && s3!="ARC"){  
        cout << "ARC" << endl;
    }
// 如果s1、s2、s3都不等于"AGC",则输出"AGC"
    else if(s1!="AGC" && s2!="AGC" && s3!="AGC"){
        cout << "AGC" << endl;
    }
// 如果s1、s2、s3都不等于"AHC",则输出"AHC"
    else if(s1!="AHC" && s2!="AHC" && s3!="AHC"){
        cout << "AHC" << endl;
    }
    
    return 0;
}

22

#include<iostream>
using namespace std;

int main(){
   int n,temp=-1;
   cin >> n ;
   string s;
   cin >> s;
   for(int i=0;i<s.size();i++){
    // 找到第一个1出现的位置,temp记录下是第几个字符(从1开始)
        if(s[i]=='1'){
            temp=i+1;
            break;
        }
   }
//偶数是Aoki,奇数是Takahashi
   if(temp%2==0){
       cout << "Aoki" << endl;
   }
   else{
       cout << "Takahashi" << endl;
   }

    return 0;
}

23

#include<iostream>
using namespace std;

int main(){
   int l,r;
   cin>>l>>r;

   string s;
   cin>>s;
// 顺序输出翻转字符串的前半部分,逆序输出翻转字符串,顺序输出翻转字符串的后半部分
   for(int i=0;i<l-1;i++){
       cout<<s[i];
   }
   for(int i=r-1;i>=l-1;i--){
       cout<<s[i];
   }
   for(int i=r;i<s.length();i++){
       cout<<s[i];
   }
    
    return 0;
}

24

#include<iostream>
using namespace std;

int main(){
   string s;
   cin>>s;
// 假设是难以阅读的字符串(奇数位置上的字符都是小写字母,偶数位置上的字符都是大写字母),难读flag为1,易读flag为0
   int flag=1;
   for(int i=0;i<s.size();i++){
    // 如果他的偶数位置上的字符是小写字母,或者奇数位置上的字符是大写字母,那么就是不难读的字符串,标志位置为0
       if((i+1)%2==0){
           if(s[i]>='a' && s[i]<='z') flag=0;
       }
       else{
           if(s[i]>='A' && s[i]<='Z') flag=0;
       }
   }

   if(flag) cout<<"Yes";
   else cout<<"No";
    
    return 0;
}

25

#include<iostream>
using namespace std;

int main(){
   int n,ac=0,wa=0,re=0,tle=0;
   cin>>n;
   string s[n+1];
   for(int i=0;i<n;i++){
       cin>>s[i];
   }

   for(int i=0;i<n;i++){
    // 遍历字符串,依次统计每个要求的个数
       if(s[i]=="AC"){
           ac++;
       }
       else if(s[i]=="WA"){
           wa++;
       }
       else if(s[i]=="RE"){
           re++;
       }
       else if(s[i]=="TLE"){
           tle++;
       }
   }
    // 注意空格,不然会报错
   cout<<"AC "<<"x "<<ac<<endl;
   cout<<"WA "<<"x "<<wa<<endl;
   cout<<"TLE "<<"x "<<tle<<endl;
   cout<<"RE "<<"x "<<re<<endl;

    return 0;
}

26

#include<iostream>
using namespace std;

int main(){
   int a,b;
   cin>>a>>b;
   string s1,s2;
   // s1是由a个b组成的,s1长度为a
   s1.resize(a);
   for(int i=0;i<a;i++){
        s1[i]='0'+b;
   }
    // s2是由b个a组成的,s2长度为b
   s2.resize(b);
    //注意字符和整数之间的转换    
   for(int i=0;i<b;i++){
        s2[i]='0'+a;
   }
   if(s1<=s2){
        cout<<s1<<endl;
    }
    else{
        cout<<s2<<endl;
    }
    
    return 0;
}

27

#include<iostream>
using namespace std;

int main(){
   string s,t;
   cin>>s>>t;
   int ss;
   ss=s.size();

    //s的大小大于t的大小,则一定不是前缀
   if(s>t)  cout<<"No"<<endl;
   else{
        string temp=t.substr(0,ss);//substr()函数用于截取字符串,第一个参数是起始位置,第二个参数是截取的长度
        if(temp==s){
            cout<<"Yes"<<endl;
        }else{
            cout<<"No"<<endl;
        }
   }
    
    
    return 0;
}

28

#include<iostream>
using namespace std;

int main(){
    int a[200010];
    int n,mx=-1;
    cin>>n;
    //找到最大值
    for(int i=1;i<=n;i++){
        cin>>a[i];
        mx=max(mx,a[i]);
    }
    //找到第二大的值
    int ans=-1,p;
    for(int i=1;i<=n;i++){
        //如果a[i]不是最大值,并且比ans大,则为第二大的值
        if(a[i]!=mx&&a[i]>ans){
            ans=a[i];
            p=i;
        }
    }
    cout<<p;
    return 0;
}

29

#include<iostream>
using namespace std;

int main(){
   int r,d,x[11];
   cin>>r>>d>>x[0];
    //注意数组下标越界问题
   for(int i=1;i<=10;i++){
       x[i]=r*x[i-1]-d;
   }
    
   for(int i=1;i<=10;i++){
      cout<<x[i]<<endl;
   }

    return 0;
}

30

无vector

#include<iostream>
using namespace std;
int main(){
	int h,w;
	cin>>h>>w;
	int a[h][w];
    //找矩阵表格中最小的数,求得矩阵中所有的数与最小的数之差的绝对值之和,即为答案
	for(int i=0;i<h;i++){
		for(int j=0;j<w;j++){
			cin>>a[i][j];
		}
	}	
    //找矩阵表格中最小的数
	int m=a[0][0];
	for(int i=0;i<h;i++){
		for(int j=0;j<w;j++){
			if(a[i][j]<m){
				m=a[i][j];
			}
		}
	}
    //求得矩阵中所有的数与最小的数之差的绝对值之和,即为答案
	int t=0;
	for(int i=0;i<h;i++){
		for(int j=0;j<w;j++){
			t+=a[i][j]-m;
		}
	}
	cout<<t<<endl;
	return 0;
}

有vector

#include<iostream>
#include <cstdlib>
#include <vector>
using namespace std;
const int MAX = 1e9 + 10;

int main(){
   int h,w,mn=MAX;
   int ans=0;
   cin>>h>>w;

   vector<vector<int>> a(h + 1, vector<int>(w + 1));
   for(int i=1;i<=h;i++){
       for(int j=1;j<=w;j++){
           cin>>a[i][j];
       }
   }
   /*
   找矩阵表格中最小的数,求得矩阵中所有的数与最小的数之差的绝对值之和,即为答案
   */
   for(int i=1;i<=h;i++){
        for(int j=1;j<=w;j++){
            if(a[i][j]<mn){
                mn=a[i][j];
            }
        }
    }

    for(int i=1;i<=h;i++){
        for(int j=1;j<=w;j++){
            ans+=abs(a[i][j]-mn);
        }
    }

    cout<<ans<<endl;
    
    return 0;
}

31-40

31 Power Socket

观察可得,从第二个插线板开始,每增加一个插线板增加\(A-1\)个插孔。可等效为初始有\(1\)个插孔,每增加一个插线板增加\(A-1\)个插孔。问题转化为计算\((B-1)/(A-1)\)向上取整。

小技巧:整数\(x,y\) 计算\(x/y\)向上取整,可等效为计算\((x+y-1)/y\)

#include<iostream>
using namespace std;
int main(){
  int a,b;
  cin>>a>>b;
  cout<<(b+a-3)/(a-1)<<endl;
  return 0;
}

32 Rally

由于数据量较小,所以直接枚举所有的整数点,计算体力值总和,找出最小值即可。

#include<iostream>
using namespace std;
int main(){
	int n;
    cin>>n;
    int x[110];
    for(int i=1;i<=n;i++){
        cin>>x[i];
    }
    int mn=0;
    for(int i=1;i<=100;i++){
        int sum=0;
        for(int j=1;j<=n;j++){
            sum+=(x[j]-i)*(x[j]-i);
        }
        if(i==1){
            mn=sum;
        }
        else{
            if(sum<mn){
                mn=sum;
            }
        }
    }
    cout<<mn<<endl;
    return 0;
}

33 Can you solve this?

模拟题,按照题意模拟即可。

#include<iostream>
using namespace std;
int main(){
	int n,m,c;
    cin>>n>>m>>c;
    int a[m],b[m];
    for(int i=0;i<m;i++){
        cin>>b[i];
    }
    int cnt=0;
    while(n--){
        for(int i=0;i<m;i++){
            cin>>a[i];
        }
        int sum=c;
        for(int i=0;i<m;i++){
            sum+=a[i]*b[i];
        }
        if(sum>0){
            cnt++;
        }
    }
    cout<<cnt<<endl;
    return 0;
}

34 Bingo

用一个二维数组来存卡片上的数字,再用另一个二维数组存标记。先将存标记的二维数组全部初始化为\(0\)。在读入每一个数字时,遍历存卡片数字的二维数组,有相同的则将对应的存标记的二维数组的位置赋值为\(1\)。最后查找满足题意的所有情况,如果某一行、某一列或某条对角线上有三个被标记的数字,则输出\(Yes\),如果没有则输出\(No\)

#include<iostream>
using namespace std;
int main(){
	int a[3][3],b[3][3];
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            cin>>a[i][j];
            b[i][j]=0;
        }
    }
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        int x;
        cin>>x;
        for(int j=0;j<3;j++){
            for(int k=0;k<3;k++){
                if(a[j][k]==x){
                    b[j][k]=1;
                }
            }
        }
    }
    for(int i=0;i<3;i++){
        if(b[i][0]==1&&b[i][1]==1&&b[i][2]==1||b[0][i]==1&&b[1][i]==1&&b[2][i]==1){
            cout<<"Yes"<<endl;
            return 0;
        }
    }
    if(b[0][0]==1&&b[1][1]==1&&b[2][2]==1||b[0][2]==1&&b[1][1]==1&&b[2][0]==1){
        cout<<"Yes"<<endl;
        return 0;
    }
    cout<<"No"<<endl;
    return 0;
}

35 1 21

首先计算 \(b\) 的位数(注意计算时不要改变 \(b\) 的值),然后拼接后的数就等于 \(a*10^{b的位数}+b\),最后计算这个数是否是完全平方数,可以选择对这个数开根号强制转换成整型后再平方,如果相等,则为完全平方数。

#include<iostream>
#include<cmath>
using namespace std;
int main(){
    int a,b;
    cin>>a>>b;
    int cnt=0;
    int bb=b;
    while(bb){
        bb/=10;
        cnt++;
    }
    int c=a*pow(10,cnt)+b;
    if((int)sqrt(c)*(int)sqrt(c)==c){
        cout<<"Yes"<<endl;
    }
    else{
        cout<<"No"<<endl;
    }
	return 0;
}

36 Collecting Balls (Easy Version)

计算每一行AB机器人哪个离小球近,相加即可

#include<iostream>
#include<cmath>
using namespace std;
int main(){
    int n,k;
    cin>>n>>k;
    int sum=0;
    for(int i=0;i<n;i++){
        int x;
        cin>>x;
        if(abs(x)>abs(k-x)){
            sum+=2*abs(k-x);
        }
        else{
            sum+=2*abs(x);
        }
    }
    cout<<sum<<endl;
}

37 Card Game for Two

每个人都会选取当前所有卡片中最大的那个,所以先降序排序,然后用偶数下标的元素和减去奇数下标的元素和的即可(下标从0开始)

#include<iostream>
#include<algorithm>
using namespace std;
bool cmp(int a,int b){
    return a>b;
}
int main(){
    int n;
    cin>>n;
    int a[n];
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    sort(a,a+n,cmp);
    int sum=0;
    for(int i=0;i<n;i++){
        if(i%2==0){
            sum+=a[i];
        }
        else{
            sum-=a[i];
        }
    }
    cout<<sum<<endl;
}

38 Break Number

如果一个数想要被2整除,首先不能是质数(除了2)。且合数是由质数相乘得来,所以让合数的因数全为2即可,即找到范围内最大的\(2^n (n可以为0)\)

#include<iostream>
#include<cmath>
using namespace std;
int main(){
    int n;
    cin>>n;
    for(int i=0;;i++){
        if(pow(2,i)>n){
            cout<<pow(2,i-1)<<endl;
            return 0;
        }
    }
    return 0;
}

39 Traveling Salesman around Lake

找出相邻两点间最大的距离,用k减去即可。

#include<iostream>
using namespace std;
int main(){
    int k,n;
    cin>>k>>n;
    int a[n];
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    int ans=0;
    for(int i=1;i<n;i++){
        if(ans<a[i]-a[i-1]){
            ans=a[i]-a[i-1];
        }
    }
    if(a[0]+k-a[n-1]>ans){
        ans=a[0]+k-a[n-1];
    }
    cout<<k-ans<<endl;
    return 0;
}

此题理论复杂度为\(O(max(a,b,c))\),所以直接暴力模拟即可。注意一种特殊情况,当\(a=b=c\)时,如果为偶数,答案为\(-1\),如果为奇数,则答案为\(0\)

#include<iostream>
using namespace std;
int main(){
    int a,b,c;
    cin>>a>>b>>c;
    if(a==b&&b==c){
        if(a%2==0){
            cout<<-1<<endl;
        }
        else{
            cout<<0<<endl;
        }
    }
    else{
        int cnt=0;
        while(a%2==0&&b%2==0&&c%2==0){
            int aa=b/2+c/2,bb=a/2+c/2,cc=a/2+b/2;
            a=aa;
            b=bb;
            c=cc;
            cnt++;
        }
        cout<<cnt<<endl;
    }
    return 0;
}

41-50

41

#include <iostream>
#include <algorithm>  // 用于min函数

using namespace std;

// 解决问题的函数
void solve() {
    // 定义变量存储输入的N和K,使用long long应对大整数
    long long initialValue, kValue;
    cin >> initialValue >> kValue;
    
    // 计算初始值除以K的余数
    // 这个余数是经过若干次操作后可能得到的一个值
    long long remainder = initialValue % kValue;
    
    // 另一个可能的最小值是K减去这个余数
    // 取这两个值中较小的那个就是答案
    long long minPossibleValue = min(remainder, kValue - remainder);
    
    // 输出结果
    cout << minPossibleValue << endl;
}

int main() {
    // 优化输入输出速度
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    // 调用解决问题的函数
    solve();
    
    return 0;
}

42

#include <iostream>
#include <vector>
#include <algorithm>  // 用于排序函数

using namespace std;

// 解决问题的函数
void solve() {
    // 读取问题数量N(题目说明N是偶数)
    int problemCount;
    cin >> problemCount;
    
    // 创建向量存储每个问题的难度
    vector<int> difficulties(problemCount);
    for (int i = 0; i < problemCount; i++) {
        cin >> difficulties[i];
    }
    
    // 对难度进行排序,方便找到中间位置
    sort(difficulties.begin(), difficulties.end());
    
    // 因为要分成数量相等的两部分,每部分的数量是N/2
    // 找到排序后位于中间的两个元素
    int middleLeft = difficulties[problemCount / 2 - 1];  // 左中间元素
    int middleRight = difficulties[problemCount / 2];     // 右中间元素
    
    // 满足条件的K值范围是(middleLeft, middleRight]
    // 所以有效的K值数量是这两个值的差
    int validKCount = middleRight - middleLeft;
    
    // 输出结果
    cout << validKCount << endl;
}

int main() {
    // 优化输入输出速度
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    // 调用解决问题的函数
    solve();
    
    return 0;
}
    

43

#include <iostream>
#include <queue>
#include <vector>

using namespace std;

// 解决问题的函数
void solve() {
    // 读取成分数量
    int ingredientCount;
    cin >> ingredientCount;
    
    // 创建最小优先队列(小顶堆),用于每次选取最小的两个元素
    // 这样可以让较大的元素尽可能晚地被平均,从而最大化最终结果
    priority_queue<double, vector<double>, greater<double>> minHeap;
    
    // 读取每个成分的值并加入优先队列
    for (int i = 0; i < ingredientCount; i++) {
        double value;
        cin >> value;
        minHeap.push(value);
    }
    
    // 不断合并两个最小的元素,直到只剩下一个元素
    while (minHeap.size() > 1) {
        // 取出最小的元素
        double firstMin = minHeap.top();
        minHeap.pop();
        
        // 取出第二小的元素
        double secondMin = minHeap.top();
        minHeap.pop();
        
        // 计算合并后的新值
        double mergedValue = (firstMin + secondMin) / 2.0;
        
        // 将合并后的值放回队列
        minHeap.push(mergedValue);
    }
    
    // 输出最后剩余元素的值,即最大可能值
    cout.precision(10);  // 保证足够的精度
    cout << minHeap.top() << endl;
}

int main() {
    // 优化输入输出速度
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    // 调用解决问题的函数
    solve();
    
    return 0;
}

44

#include <iostream>
#include <string>

using namespace std;

// 检查字符是否为ACGT中的一个
bool isAcgtChar(char c) {
    return (c == 'A' || c == 'C' || c == 'G' || c == 'T');
}

// 解决问题的函数
void solve() {
    // 读取输入字符串
    string inputStr;
    cin >> inputStr;
    
    // 记录最长ACGT子串的长度
    int maxLength = 0;
    // 记录当前连续ACGT子串的长度
    int currentLength = 0;
    
    // 遍历字符串中的每个字符
    for (char c : inputStr) {
        if (isAcgtChar(c)) {
            // 如果是ACGT字符,当前长度加1
            currentLength++;
            // 更新最长长度(如果当前更长)
            if (currentLength > maxLength) {
                maxLength = currentLength;
            }
        } else {
            // 如果不是ACGT字符,重置当前长度
            currentLength = 0;
        }
    }
    
    // 输出结果
    cout << maxLength << endl;
}

int main() {
    // 优化输入输出速度
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    // 调用解决问题的函数
    solve();
    
    return 0;
}

45

#include <iostream>
#include <map>

using namespace std;

// 解决问题的函数
void solve() {
    // 读取初始值s
    int currentValue;
    cin >> currentValue;
    
    // 创建一个映射来记录每个数值出现的次数
    map<int, int> valueCount;
    
    // 记录初始值出现过一次
    valueCount[currentValue]++;
    
    // 记录当前是序列的第几个元素(从1开始)
    int position = 1;
    
    // 循环生成下一个元素,直到找到重复的值
    while (true) {
        // 生成下一个位置的元素
        position++;
        
        // 根据当前值是奇数还是偶数,计算下一个值
        if (currentValue % 2 == 1) {
            // 奇数:3n + 1
            currentValue = 3 * currentValue + 1;
        } else {
            // 偶数:n / 2
            currentValue /= 2;
        }
        
        // 记录当前值出现的次数
        valueCount[currentValue]++;
        
        // 如果当前值已经出现过一次以上,说明找到了重复
        if (valueCount[currentValue] > 1) {
            // 输出当前位置并结束函数
            cout << position << endl;
            return;
        }
    }
}

int main() {
    // 关闭输入输出同步,提高效率
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    // 调用解决问题的函数
    solve();
    
    return 0;
}

46

#include <iostream>

using namespace std;

// 计算涂色方案数的函数
void calculatePaintingWays() {
    // 读取输入:N为球的数量,K为颜色的数量
    int ballCount, colorCount;
    cin >> ballCount >> colorCount;
    
    // 存储结果的变量,初始化为1
    int result = 1;
    
    // 计算涂色方案数:
    // 第一个球可以用K种颜色中的任意一种
    // 从第二个球开始,每个球都不能和前一个球颜色相同,所以有(K-1)种选择
    for (int i = 1; i <= ballCount; ++i) {
        if (i == 1) {
            // 第一个球的选择数
            result *= colorCount;
        } else {
            // 后续每个球的选择数(不能和前一个相同)
            result *= (colorCount - 1);
        }
    }
    
    // 输出结果
    cout << result << endl;
}

int main() {
    // 关闭输入输出同步,提高效率
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    // 调用计算函数
    calculatePaintingWays();
    
    return 0;
}
    

47

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// 解决问题的函数:计算购买M罐能量饮料的最小花费
void calculateMinCost() {
    // 读取商店数量N和需要购买的饮料数量M
    int storeCount, needCount;
    cin >> storeCount >> needCount;
    
    // 存储每个商店的信息:价格和可购买数量
    vector<pair<int, int>> stores(storeCount);
    
    // 读取每个商店的价格和最大可购买数量
    for (int i = 0; i < storeCount; ++i) {
        // first存储价格,second存储可购买数量
        cin >> stores[i].first >> stores[i].second;
    }
    
    // 按价格从低到高排序商店,优先购买便宜的饮料
    sort(stores.begin(), stores.end());
    
    // 已购买的饮料数量
    int purchasedCount = 0;
    // 总花费
    long long totalCost = 0;
    
    // 遍历每个商店,按价格从低到高购买
    for (int i = 0; i < storeCount; ++i) {
        int price = stores[i].first;       // 当前商店的单价
        int available = stores[i].second;  // 当前商店可购买的最大数量
        
        // 如果当前商店的所有饮料都可以买下(还没买够M罐)
        if (purchasedCount + available <= needCount) {
            purchasedCount += available;
            totalCost += (long long)available * price;
        } else {
            // 只需要购买剩余需要的数量
            int remaining = needCount - purchasedCount;
            totalCost += (long long)remaining * price;
            break;  // 已经买够了,退出循环
        }
    }
    
    // 输出最小花费
    cout << totalCost << endl;
}

int main() {
    // 关闭输入输出同步,提高效率
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    // 调用计算函数
    calculateMinCost();
    
    return 0;
}
    

48

#include <iostream>
#include <algorithm> // 用于max函数

using namespace std;

// 计算使三个数相等的最少操作次数
void calculateMinOperations() {
    // 读取三个整数A、B、C
    int a, b, c;
    cin >> a >> b >> c;
    
    // 找到三个数中的最大值,最终三个数都会等于这个最大值或更大的值
    int maxVal = max({a, b, c});
    
    // 计算每个数与最大值的差值之和
    // 这个和表示总共需要增加的数值
    int totalDiff = (maxVal - a) + (maxVal - b) + (maxVal - c);
    
    // 分析操作次数:
    // 每次操作1(选两个数各+1)增加总和2,每次操作2(选一个数+2)也增加总和2
    // 因此总操作次数与总差值的关系取决于总差值的奇偶性
    
    if (totalDiff % 2 == 0) {
        // 总差值为偶数时,操作次数是总差值的一半
        cout << totalDiff / 2 << endl;
    } else {
        // 总差值为奇数时,需要多进行一次操作(+2和+1的组合)
        // 此时相当于总差值+3后再除以2
        cout << (totalDiff + 3) / 2 << endl;
    }
}

int main() {
    // 关闭输入输出同步,提高效率
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    // 调用计算函数
    calculateMinOperations();
    
    return 0;
}
    

49

#include <iostream>
#include <string>

using namespace std;

int main() {
    // 读取输入的四位数字符串
    string fourDigits;
    cin >> fourDigits;
    
    // 从字符串中提取四个数字(将字符转换为整数)
    int first = fourDigits[0] - '0';  // 第一位数字
    int second = fourDigits[1] - '0'; // 第二位数字
    int third = fourDigits[2] - '0';  // 第三位数字
    int fourth = fourDigits[3] - '0'; // 第四位数字
    
    // 定义运算符对应的数值:1代表加号(+),-1代表减号(-)
    int operators[] = {1, -1};
    
    // 枚举所有可能的运算符组合(共有2×2×2=8种可能)
    for (int op1 : operators) {
        for (int op2 : operators) {
            for (int op3 : operators) {
                // 计算当前运算符组合下的表达式结果
                int result = first + op1 * second + op2 * third + op3 * fourth;
                
                // 如果结果等于7,说明找到了正确的表达式
                if (result == 7) {
                    // 输出表达式
                    cout << first;
                    cout << (op1 == 1 ? '+' : '-');  // 根据op1的值输出+或-
                    cout << second;
                    cout << (op2 == 1 ? '+' : '-');  // 根据op2的值输出+或-
                    cout << third;
                    cout << (op3 == 1 ? '+' : '-');  // 根据op3的值输出+或-
                    cout << fourth << "=7" << endl;
                    
                    // 找到答案后直接结束程序
                    return 0;
                }
            }
        }
    }
    
    return 0;
}
    

50

#include <iostream>
using namespace std;

/**
 * 计算一个数能被100整除的次数
 * @param number 要检查的数字
 * @return 能被100整除的次数
 */
int count100Divisions(int number) {
    int divisionCount = 0;
    // 只要能被100整除,就继续除以100并计数
    while (number % 100 == 0) {
        divisionCount++;
        number /= 100;
    }
    return divisionCount;
}

int main() {
    // D是需要被100整除的次数,N是要找的第N小的数
    int requiredDivisions, targetPosition;
    cin >> requiredDivisions >> targetPosition;
    
    int foundCount = 0;  // 已找到的符合条件的数字数量
    int currentNumber = 1;  // 当前检查的数字
    
    // 循环查找,直到找到第N个符合条件的数字
    while (true) {
        // 检查当前数字是否正好能被100整除requiredDivisions次
        if (count100Divisions(currentNumber) == requiredDivisions) {
            foundCount++;  // 找到一个符合条件的数字
            
            // 如果已找到第N个,输出并结束程序
            if (foundCount == targetPosition) {
                cout << currentNumber << endl;
                return 0;
            }
        }
        currentNumber++;  // 检查下一个数字
    }
    
    return 0;
}
    
posted @ 2025-10-06 23:02  LYET  阅读(159)  评论(0)    收藏  举报