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;
}
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字符,当前长度加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;
}

浙公网安备 33010602011771号