暑期第一场题解

A

此题,emmmm,有毒,很容易出现各种bug,还是自己菜,不能动不动就觉得是数据有问题,此题肯定要用字符串,模拟的题,代码有点长(蒟蒻瑟瑟发抖),不过不难理解,仔细看看就明白了,主要是细节方面的处理
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
int main()
{                                          //肯定不是最优的,而且还很冗长,是我太菜了
	string a, b;
	char c[1000];                       //这里要用到char,因为我vs过不了,嘤嘤嘤
	int t, i, j, lag , m, o = 1, n;     //lag是进位,m是c数组的下标,用n赋值为t,下面会解释
	cin >> t;
	n = t;
	while (t--)
	{
		cin >> a >> b;
		m = 0; lag = 0;             //下面会将两个字符串相加一直到其中一个结束,因为位数不一定相等
		for (i = a.size() - 1, j = b.size() - 1; i >= 0 && j >= 0; i--, j--)
		{                                           //size函数是计算字符串长度的
			c[m] = a[i] + b[j] - 48 + lag;      //根据asc码来运算,lag为进位
			lag = 0;                            //赋值0,只有有进位时才为1
			if (c[m]>57)
			{
				c[m] -= 10;
				lag = 1;
			}
			m++;
		}
		if (a.size() == b.size())          //如果字符串长度相等,证明已经相加结束,只判断最高位是否有进位
		{
			if (lag)                   //如果有,那么最高位只会为1
				c[m++] = 49;
		}
		if (a.size()>b.size())             //如果第一个字符串长,那么继续拿进位和第一个字符串相加,
		{                                  //比如说123+9,3与9相加后,1,2要继续和进位相加
			if (lag)                   //两种情况,第一种,有进位
			{
				for (; i >= 0; i--)  //i不用赋初值,因为i即为上次相加的位置
				{
					c[m] = a[i] + lag;
					if (c[m] > 57)   //这里应该不难理解
					{
						c[m] -= 10;
						lag = 1;
					}
					else
						lag = 0;
					m++;
				}
				if (lag)                //这是最高位计算后,再判断最高位是否有进位
					c[m++] = 49;
			}
			else                          //第二种情况,没有进位,则保持原值不用再计算
			{
				for (; i >= 0; i--)
					c[m++] = a[i];
			}
		}
		if (a.size()<b.size())                //当第二个字符串位数较多时同上
		{
			if (lag)
			{
				for (; j >= 0; j--)
				{
					c[m] = b[j] + lag;
					if (c[m] > 57)
					{
						c[m] -= 10;
						lag = 1;
					}
					else
						lag = 0;
					m++;
				}
				if (lag)
					c[m++] = 49;
			}
			else
			{
				for (; j >= 0; j--)
					c[m++] = b[j];
			}
		}
		cout << "Case " << o << ":" << endl;    //最后要说一下输出,要严格按照题目要求,注意数字间有空格
		cout << a << " + " << b << " = ";       
		for (i = m - 1; i >= 0; i--)
			cout << c[i];
		cout << endl;                          //每组数据最后都要换行,endl就是换行的意思,但每两组数据间要空上一行
		if (o<n)                               //所以要用到n,假如有3组数据,o初值为1,所以只有为1,2时才空行,即1与2,2与3之间空行
			cout << endl;
		o++;
	}
	return 0;                                      //光A题题解就写到12点了,睡觉喽
}


B

此题可以用递归函数,不过很容易就超出内存限制了,可以将其适当优化,根据公式a%m+b%m=(a+b)%m,而a和b取值0到6

共49种情况,往后就会循环重复,故可将n改为n%49优化,

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int Fn(int A,int B,long n);
	long n;
	int a,b,c;
	while(cin>>a>>b>>n && a+b+n)    //如果3个数都为0,不满足条件
	{
		c=Fn(a,b,n%49);      //此处是重点
		cout<<c<<endl;
	}
	return 0;
 } 
 
int Fn(int A,int B,long n)
{
	if(n==1||n==2)
		return 1;
	else
		return (A*Fn(A,B,n-1)+B*Fn(A,B,n-2))%7; //递归调用
}

C

这题我还是有点懵的,在网上看了很多讲解大致明白了思路,注意,对称位置上的结果一样,就只需考虑4种情况,先手下棋不会输,可根据数组a理解

#include<iostream>
#include<string>
using namespace std;
int a[4][5];                 //定义全局变量,函数可以直接引用
void xiaqi() 
{
    a[1][1]=a[1][4]=a[3][1]=a[3][4]=6;
    a[1][2]=a[1][3]=a[2][2]=a[2][3]=a[3][2]=a[3][3]=4;
    a[2][1]=a[2][4]=0;
}
int main()
{
	int t,x,y;
	cin>>t;
	xiaqi();
	while(t--)
	{
		cin>>x>>y;     // 输入x和y
		if(a[x][y]==0)
		{
			cout<<"equal"<<endl;
			cout<<"0"<<endl;
		}
		else
		{
			cout<<"win"<<endl;
			cout<<a[x][y]<<endl;
		}
	}
	return 0;
}

D

此题关键是理解题意,就是让你判断是不是对串,是的话就满足条件

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
	string s;
	int i,l;
	bool lag=true;          
	cin>>s;             //输入字符串
	l=s.size();
	if(l%2!=0)          //如果是奇数个字符,肯定不是对串
		lag=false;
	for(i=0;i<l/2;i++)           //依次比较判断
		if(s[i]!=s[i+l/2])
			lag=false;
	if(lag)
		cout<<"YES"<<endl;
	else
		cout<<"NO"<<endl;
	return 0;
 } 

E

此题要用栈来写,栈就相当于羽毛球筒,先进去的羽毛球最后出来,先大致了解栈就行,不懂也不妨碍理解本题

方向向右的鱼儿入栈,与往左的比较大小,具体看代码理解

#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
typedef struct fish                  //用typedef定义结构体,Fish就相当于struct fish
{
	long a;
	int b;
}Fish;
Fish s[100000];                     //定义一个结构体数组 
long z[100000];                     //定义一个大数组要定义成全局变量,否则数组过大会报错
int main()                         
{
	long n,i,j,count=0,t=0;
	cin>>n;
	for(i=0;i<n;i++)              
	{
		cin>>s[i].a>>s[i].b;
	}
	for(i=0;i<n;i++)                       //从左到右开始依次匹配
	{
		if(s[i].b==1)                  //如果往右游,让其入栈,即将其存入一个新数组里面
			z[t++]=s[i].a;         //注意,t是在栈(新数组)中鱼儿的数量
		if(s[i].b==0 && t>0)           //如果遇见往左的,并且栈里有鱼儿(即这个鱼儿左边有往右去的鱼),比较大小,看谁吃谁
		{
			if(s[i].a<z[t-1])
				count++;       //如果栈里的鱼大,它仍然存活,count是被吃掉的鱼的数量,加一
			else
			{                      
				i--;           //i减一,继续让这条鱼和栈里的鱼比较
				t--;           //栈中鱼数量减一
				count++;        //被吃掉鱼的数量加一
			}
		}
	} 
	 cout<<n-count<<endl;      //输出剩下多少鱼
     return 0;
}



F

这个题比较简单
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
int main()
{
	int t,k,n,n1,n2,i,a[4];
	cin>>t;
	while(t--)
	{
		cin>>n>>k;
		while(k--)
		{
			n1=0;n2=0;
			a[0]=n/1000;
			a[1]=(n/100)%10;
			a[2]=(n%100)/10;
			a[3]=n%10;
			sort(a,a+4);
			for(i=0;i<4;i++)
			{
				
				n1+=a[i]*pow(10,i);  
				n2+=a[3-i]*pow(10,i);
			}
			n=abs(n1-n2);
		}
		cout<<n<<endl;
	}
	return 0;
 } 

G

这题是字典序排列,算法很麻烦,果然有库就是好,现成函数让你用

#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
int main()                         
{
	string s;
	cin >> s;
	int a[10];
	for(int i=0;i<s.size();i++)
		a[i]=s[i]-'0';
	sort(a,a+s.size());
	do
	{
		for(int i=0;i<s.size();i++)
			cout<<a[i];
		cout<<endl;
	}
	while(next_permutation(a,a+s.size()));
     return 0;
}

H

上次的原题,先打表,再查询即可

#include<stdio.h>
int main()
{
	long q, i, n, s, l;
        long long a[50001], b, c;
	scanf("%ld", &n);
	a[0] = 0;
	for (i = 1; i <= n; i++)
	{
		scanf("%lld", &b);
		a[i] = a[i - 1] + b;
	}
	scanf("%ld", &q);
	while (q--)
	{
		scanf("%ld%ld", &s, &l);
		c = a[s + l - 1] - a[s - 1];
		printf("%lld\n", c);
	}
	return 0;
}

I

此题听说冒泡会超时,我直接用的sort函数(快速排序),
#include<iostream>
#include<algorithm>
using namespace std;
long a[50000];
int main()
{
	long n,i;
	cin>>n;
	for(i=0;i<n;i++)
	cin>>a[i];
	sort(a,a+n);             //起始地址,结束地址
	for(i=0;i<n;i++)
	cout<<a[i]<<endl;
	return 0;
 } 

J

这道题就是让你判断是不是存在ABC这类3个全排列,我写了个函数用来判断
#include<iostream>
#include<string>
using namespace std;
int main()
{
	int sanse(string b,string a);
	string a;
	cin>>a;                             //分别判断这6种情况,只要有一种满足就符合条件
	if(sanse("ABC",a)||sanse("ACB",a)||sanse("BAC",a)||sanse("BCA",a)||sanse("CAB",a)||sanse("CBA",a))
		cout<<"Yes"<<endl;
	else
		cout<<"No"<<endl;
		return 0;
}

int sanse(string b,string a)           //这个函数判断的核心跟上次A题一样,不清楚的可以看我上次写的A题
{
	int i,j,t;
	for(i=0;i<a.size();i++)
	{
		if(a[i]==b[0])
		{
			t=1;
			for(j=1;j<3;j++)
				if(a[i+j]==b[j])
					t++;
			if(t==3)
			return true;
		}
	}
	return false;
}

K

这题说白了就是讲其排序,然后一个从头开始,一个从尾开始,剩下最后一个即是所求
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
int main()
{
	int n,i;
	long a[1000];
	cin>>n;
	for(i=0;i<n;i++)
		cin>>a[i]; 
	sort(a,a+n);                   //从大到小排序
	if(n==1||n==2)                 //此时都是第一个剩下来
		cout<<a[0]<<endl;
	else
	{
		if(n%2==0)
			cout<<a[n/2 - 1]<<endl;
		else
			cout<<a[n/2]<<endl;
	}
	return 0;
 } 

L

其实两个都差不多,第一个是枚举,第二个是我刚开始想的

#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
int main()
{
	long long a,b,y;
	long long n,m,f1,f2;
	cin>>n>>m>>a>>b;
	y=n/m;
	if(n%m==0)
		cout<<"0"<<endl;
	else
	{
		f1=((y+1)*m-n)*a;                   //不明白的可以代入计算一下
		f2=(n-m*y)*b;
		cout<<min(f1,f2)<<endl;
	}
	return 0;
 } 

#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
int main()
{
	long long a,b,y;                        //注意,刚开始我给的int,结果咳咳,,没过,,
	long long n,m,f1,f2;
	cin>>n>>m>>a>>b;
	y=n%m;
	if(y==0)                                //如果整除,不用再计算
		cout<<"0"<<endl;
	else
	{
		f1=y*b;                            //感觉这个好理解
		f2=(m-y)*a;
		if(f1<f2)
			cout<<f1<<endl;
		else
			cout<<f2<<endl;
	}
	return 0;
 } 


猜你喜欢

转载自blog.csdn.net/qq_41785863/article/details/81003712