【LGR-(-6)】洛谷入门赛 #3

题目链接
由于比赛已经结束,附上每个题目的链接
A【深基2.例7】数字反转
B【深基3.例3】闰年判断
C【深基3.习8】三角形分类
D【深基4.例13】质数口袋
E【深基5.例7】工艺品制作
F【深基7.例1】距离函数
G【深基7.例10】旗鼓相当的对手 - 加强版
H【深基9.例4】求第 k 小的数
I 【深基16.例1】淘汰赛
昨天也是第一次参加洛谷的比赛,个人觉得比赛还是不错的可以锻炼一下自己,检验一下自己学的扎不扎实,更利于查漏补缺!!!
对代码有疑惑或者不明白的地方直接发评论区即可~
下面附上每个题目的AC代码

A 数字反转
直接逆序输出即可

//直接利用string存储逆序输出
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
    string a;
    cin>>a;
    for(int i=a.length()-1;i>=0;i--)cout<<a[i];
}

B 闰年判断
判断闰年的条件:能被 4 整除,但是不能被100整除或者能被400整除

#include<bits/stdc++.h>
using namespace std;
int main() {
	long long y;
	cin>>y;
	if(y%400==0||y%4==0&&y%100!=0)//闰年判断条件
	{
		cout<<1<<endl;
	}
	else
	{
		cout<<0<<endl;	
	}
	return 0;
}

C 三角形分类
先判断输入的三条边是否合法,然后根据边来判断三角形的属性,满足一条输出一条即可。

#include<bits/stdc++.h>
using namespace std;
int main() {
	int a,b,c;
	cin>>a>>b>>c;
	if(a+b<=c||a+c<=b||c+b<=a) {
		cout<<"Not triangle"<<endl;
		return 0;
	}
	if(a*a+b*b==c*c||c*c+b*b==a*a||a*a+c*c==b*b) {
		cout<<"Right triangle"<<endl;
	} else if(a*a+b*b<c*c||c*c+b*b<a*a||a*a+c*c<b*b) {
		cout<<"Obtuse triangle"<<endl;
	} else if(a*a+b*b>c*c||c*c+b*b>a*a||a*a+c*c>b*b) {
		cout<<"Acute triangle"<<endl;
	}
	if(a==b||b==c||a==c) {
		cout<<"Isosceles triangle"<<endl;
	}
	if(a==b&&b==c) {
		cout<<"Equilateral triangle"<<endl;
	}
	return 0;
}

D 质数口袋
判断质数的方法:根据数论理论可以把数字分成6个大部分,6i,6i+1,6i+2,6i+3,6i+4,6i+5,也就是说数字x%6计算的值一定是0,1,2,3,4,5这6个数字,而6i,6i+2,6i+3,6i+4一定就是合数,它们都有除了1之外的因数,只有6i+1和6i+5可能是素数,因而一旦判定数字大于等于且6取模结果为0,2,3,4就可以判定不是素数。

#include<bits/stdc++.h>
using namespace std;
bool vis;
int check(int temp) {
	if(temp==1||temp==2||temp==3) {
		return 1;
	} else if(temp%6!=1&&temp%6!=5) {
		return 0;
	}
	for(int i=5; i<=sqrt(temp); i+=6) {
		if(temp%i==0||temp%(i+2)==0) {
			return 0;
		}
	}
	return 1;
}
int main() {
	int L,sum=0,num=0;
	cin>>L;
	if(L==1)
	{
		cout<<0<<endl;
		return 0;
	}
	for(int i=2;i<=L;i++){
		if(check(i)){
			sum+=i;
			num++;	
			if(sum>L){
				vis=1;
			}
			else
			{
				cout<<i<<endl;
			}
		}
		if(vis){
			sum-=i;
			num--;
			break;
		}
	}
	cout<<num<<endl;
	return 0;
}

E 工艺品制作
这个题目直接暴力求解,枚举所有点的状态进行统计即可,要注意一点就是每个输入的点也会被蒸发

#include<bits/stdc++.h>
using namespace std;
int a[100][100][100];
int main(){
	int w,x,h,q,sum=0;
	int x1,x2,y1,y2,z1,z2;
	cin>>w>>x>>h>>q;
	while(q--){
		cin>>x1>>y1>>z1>>x2>>y2>>z2;
		for(int i=x1;i<=x2;i++){
			for(int j=y1;j<=y2;j++){
				for(int t=z1;t<=z2;t++){
					a[i][j][t]=1;
					//cout<<i<<" "<<j<<" "<<t<<endl;
				}
			}
		}
	}
	for(int i=1;i<=w;i++){
		for(int j=1;j<=x;j++){
			for(int t=1;t<=h;t++){
				if(!a[i][j][t]){
					sum++;
				}
			}
		}
	}
	cout<<sum<<endl;
	return 0;
} 

F 距离函数
直接用两点间距离公式求即可

#include<bits/stdc++.h>
using namespace std;
int main() {
	double x1,y1,x2,y2,x3,y3,l1,l2,l3;
	cin>>x1>>y1>>x2>>y2>>x3>>y3;
	l1=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
	l2=sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2));
	l3=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));
	printf("%.2f\n",l1+l2+l3);
	return 0;
}

G 旗鼓相当的对手 - 加强版
这个题目注意输出顺序即可,我没仔细读题WA了好多次
先对一个组内的排序,将字典序小的放到前面,然后对组合进行排序,先把每个组里第一个拿出来比较,如果相等比较第二个,将字典序小的放到前面。

#include<bits/stdc++.h>
using namespace std;
struct stu {
	string name;
	int sc[5];
	int all;
} s[105000];
struct zan {
	string name1;
	string name2;
} tu[105000];
bool cmp(zan a,zan b) {
	if(a.name1==b.name1) {
		return a.name2<b.name2;
	} else {
		return a.name1<b.name1;
	}
}
int main() {
	int n,d=0,num=0;
	cin>>n;
	for(int i=0; i<n; i++) {
		//cin>>s[i].sc[0]>>s[i].sc[1]>>s[i].sc[2];
		cin>>s[i].name>>s[i].sc[0]>>s[i].sc[1]>>s[i].sc[2];
		s[i].all=s[i].sc[0]+s[i].sc[1]+s[i].sc[2];
	}
	for(int i=0; i<n; i++) {
		for(int j=i+1; j<n; j++) {
			if(abs(s[i].all-s[j].all)<=10) {
				int temp=0;
				if(abs(s[i].sc[0]-s[j].sc[0])<=5&&abs(s[i].sc[1]-s[j].sc[1])<=5&&abs(s[i].sc[2]-s[j].sc[2])<=5) {
					temp=1;
				}
				if(temp==1) {
					if(s[i].name<s[j].name) {
						tu[d].name1=s[i].name;
						tu[d].name2=s[j].name;
						d++;
					} else {
						tu[d].name1=s[j].name;
						tu[d].name2=s[i].name;
						d++;
					}
				}
			}
		}
	}
	sort(tu,tu+d,cmp);
	for(int i=0; i<d; i++) {
		cout<<tu[i].name1<<" "<<tu[i].name2<<endl;
	}
	return 0;
}

H 求第 k 小的数
这个道题就比较(keng)好了
sort函数直接TLE
自己写了一个优化的快排还是超
改了n(忘记多少次了)次终于不超了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int patition(int a[], int left, int right){ //对 left ~  right 进行划分 
	int x = a[left];
	while(left < right){
		while(left<right && a[right]>=x)
			right--;
		a[left] = a[right];
		while(left<right && a[left]<=x)
			left++;
		a[right] = a[left];
	}
	a[left] = x;
	return left;
}

void find(int a[], int left, int right, int k){	//在 left ~  right 寻找 
	int pos = patition(a, left, right);
	if(pos == k)
		printf("%d\n", a[pos]);
	else if(pos > k)
		find(a, left, pos-1, k);
	else 
		find(a, pos+1, right, k);
}

int main(){
	int n, k, a[5000005];
	scanf("%d%d", &n, &k);
	k++;//题目要求是从0开始,我下面写的下标是从1开始的,因此加1
	for(int i=1; i<=n; i++) 
		scanf("%d", a+i);
	find(a, 1, n, k);
}

I 淘汰赛
看起来很麻烦,无从下手,仔细分析题意
其实就是数组前一半的最大值与后一半的最大值比较,找到小的值的下标

#include<bits/stdc++.h>
using namespace std;
int a[1024];
int main() {
	int n,all,c,b,max1,max2;
	cin>>n;
	all=pow(2,n);
	for(int i=1; i<=all; i++) {
		cin>>a[i];
	}
	//cout<<a[1]<<" "<<a[all/2+1]<<endl;
	//cout<<all/2+1<<endl;
	c=1;
	b=all/2+1;
	max1=a[1],max2=a[all/2+1];
	for(int i=1; i<=all/2; i++) {
		if(a[i]>max1) {
			c=i;
			max1=a[i];
		}
		if(a[i+all/2]>max2) {
			b=i+all/2;
			max2=a[i+all/2];
		}
	}
	//cout<<c<<b<<endl;
	if(max2>max1) {
		cout<<c<<endl;
	} else {
		cout<<b<<endl;
	}
	return 0;
}

转载务必附上本文链接!!!

扫描二维码关注公众号,回复: 8711035 查看本文章
发布了16 篇原创文章 · 获赞 12 · 访问量 2051

猜你喜欢

转载自blog.csdn.net/weixin_44417475/article/details/104041858