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==xfor(int i = 0;i<int(s.size());i++){ // 为什么推荐把s.size()转成int前面有说if(s[i] == 'x'){ // 如果当前字符为‘x’,并且当前分数大于0,分数-1if(ans>0) ans--;}else{ // 否则分数+1ans++;}}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,直接输出scout << 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,奇数是Takahashiif(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为0int flag=1;for(int i=0;i<s.size();i++){// 如果他的偶数位置上的字符是小写字母,或者奇数位置上的字符是大写字母,那么就是不难读的字符串,标志位置为0if((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长度为as1.resize(a);for(int i=0;i<a;i++){s1[i]='0'+b;}// s2是由b个a组成的,s2长度为bs2.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;
}
40 Cookie Exchanges
此题理论复杂度为\(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字符,当前长度加1currentLength++;// 更新最长长度(如果当前更长)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() {// 读取初始值sint currentValue;cin >> currentValue;// 创建一个映射来记录每个数值出现的次数map<int, int> valueCount;// 记录初始值出现过一次valueCount[currentValue]++;// 记录当前是序列的第几个元素(从1开始)int position = 1;// 循环生成下一个元素,直到找到重复的值while (true) {// 生成下一个位置的元素position++;// 根据当前值是奇数还是偶数,计算下一个值if (currentValue % 2 == 1) {// 奇数:3n + 1currentValue = 3 * currentValue + 1;} else {// 偶数:n / 2currentValue /= 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;// 存储结果的变量,初始化为1int 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和需要购买的饮料数量Mint 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、Cint 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后再除以2cout << (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;
}